upleb.uk

Public git repos — served from a NIP-34 GRASP relay at git.upleb.uk

summaryrefslogtreecommitdiff
path: root/tests/unit
diff options
context:
space:
mode:
Diffstat (limited to 'tests/unit')
-rw-r--r--tests/unit/Makefile14
-rw-r--r--tests/unit/stubs/dns_server.h11
-rw-r--r--tests/unit/stubs/esp_wifi_ap_get_sta_list.h38
-rw-r--r--tests/unit/stubs/freertos/task.h7
-rw-r--r--tests/unit/stubs/lwip/etharp.h22
-rw-r--r--tests/unit/stubs/lwip/ip4_addr.h3
-rw-r--r--tests/unit/stubs/lwip/lwip_napt.h (renamed from tests/unit/stubs/lwip/napt.h)0
-rw-r--r--tests/unit/stubs/lwip/netif.h16
-rw-r--r--tests/unit/stubs/lwip/prot/ip.h20
-rw-r--r--tests/unit/stubs/lwip/prot/ip4.h6
-rw-r--r--tests/unit/stubs/lwip/prot/tcp.h13
-rw-r--r--tests/unit/stubs/lwip/sockets.h6
-rwxr-xr-xtests/unit/test_firewall_sandboxbin0 -> 30576 bytes
-rw-r--r--tests/unit/test_firewall_sandbox.c94
-rwxr-xr-xtests/unit/test_identitybin297888 -> 297888 bytes
-rwxr-xr-xtests/unit/test_mcp_handlerbin64152 -> 64152 bytes
-rwxr-xr-xtests/unit/test_session_payment_methodbin0 -> 54008 bytes
-rw-r--r--tests/unit/test_session_payment_method.c74
-rwxr-xr-xtests/unit/test_stratum_proxybin0 -> 40752 bytes
-rw-r--r--tests/unit/test_stratum_proxy.c95
-rwxr-xr-xtests/unit/test_tollgate_clientbin52968 -> 52968 bytes
-rwxr-xr-xtests/unit/test_tollgate_client_miningbin0 -> 47224 bytes
-rw-r--r--tests/unit/test_tollgate_client_mining.c103
23 files changed, 519 insertions, 3 deletions
diff --git a/tests/unit/Makefile b/tests/unit/Makefile
index 0a726f6..aa7f5ae 100644
--- a/tests/unit/Makefile
+++ b/tests/unit/Makefile
@@ -22,7 +22,7 @@ LDFLAGS := -lmbedcrypto -lcjson -lm
22 22
23SECP256K1_OBJ := secp256k1.o precomputed_ecmult.o precomputed_ecmult_gen.o 23SECP256K1_OBJ := secp256k1.o precomputed_ecmult.o precomputed_ecmult_gen.o
24 24
25TESTS := test_geohash test_identity test_nostr_event test_cashu test_session test_tollgate_client test_lnurl_pay test_lightning_payout test_mcp_handler test_nip04 test_cvm_server test_mining_payment 25TESTS := test_geohash test_identity test_nostr_event test_cashu test_session test_tollgate_client test_lnurl_pay test_lightning_payout test_mcp_handler test_nip04 test_cvm_server test_mining_payment test_stratum_proxy test_session_payment_method test_tollgate_client_mining test_firewall_sandbox
26 26
27.PHONY: all test clean $(TESTS) 27.PHONY: all test clean $(TESTS)
28 28
@@ -84,5 +84,17 @@ test_cvm_server: test_cvm_server.c
84test_mining_payment: test_mining_payment.c $(REPO_ROOT)/main/mining_payment.c 84test_mining_payment: test_mining_payment.c $(REPO_ROOT)/main/mining_payment.c
85 $(CC) $(CFLAGS) $< $(REPO_ROOT)/main/mining_payment.c -o $@ $(LDFLAGS) 85 $(CC) $(CFLAGS) $< $(REPO_ROOT)/main/mining_payment.c -o $@ $(LDFLAGS)
86 86
87test_stratum_proxy: test_stratum_proxy.c $(REPO_ROOT)/main/stratum_proxy.c $(REPO_ROOT)/main/mining_payment.c
88 $(CC) $(CFLAGS) $< $(REPO_ROOT)/main/stratum_proxy.c $(REPO_ROOT)/main/mining_payment.c -o $@ $(LDFLAGS)
89
90test_session_payment_method: test_session_payment_method.c $(REPO_ROOT)/main/session.c $(REPO_ROOT)/main/cashu.c
91 $(CC) $(CFLAGS) $< $(REPO_ROOT)/main/session.c $(REPO_ROOT)/main/cashu.c -o $@ $(LDFLAGS)
92
93test_tollgate_client_mining: test_tollgate_client_mining.c
94 $(CC) $(CFLAGS) $< -o $@ $(LDFLAGS)
95
96test_firewall_sandbox: test_firewall_sandbox.c $(REPO_ROOT)/main/firewall.c
97 $(CC) $(CFLAGS) -include stubs/dns_server.h $< $(REPO_ROOT)/main/firewall.c -o $@ $(LDFLAGS)
98
87clean: 99clean:
88 rm -f $(TESTS) $(SECP256K1_OBJ) 100 rm -f $(TESTS) $(SECP256K1_OBJ)
diff --git a/tests/unit/stubs/dns_server.h b/tests/unit/stubs/dns_server.h
new file mode 100644
index 0000000..0a9450b
--- /dev/null
+++ b/tests/unit/stubs/dns_server.h
@@ -0,0 +1,11 @@
1#ifndef STUBS_DNS_SERVER_H
2#define STUBS_DNS_SERVER_H
3
4#include <stdint.h>
5#include <stdbool.h>
6
7static inline void dns_server_set_client_authenticated(uint32_t ip, bool auth) {
8 (void)ip; (void)auth;
9}
10
11#endif
diff --git a/tests/unit/stubs/esp_wifi_ap_get_sta_list.h b/tests/unit/stubs/esp_wifi_ap_get_sta_list.h
new file mode 100644
index 0000000..3e98032
--- /dev/null
+++ b/tests/unit/stubs/esp_wifi_ap_get_sta_list.h
@@ -0,0 +1,38 @@
1#ifndef STUBS_ESP_WIFI_AP_GET_STA_LIST_H
2#define STUBS_ESP_WIFI_AP_GET_STA_LIST_H
3
4#include <stdint.h>
5#include <string.h>
6#include "esp_err.h"
7
8#define ESP_WIFI_AP_MAX_STA 10
9
10typedef struct {
11 uint8_t mac[6];
12} wifi_sta_info_t;
13
14typedef struct {
15 int num;
16 wifi_sta_info_t sta[ESP_WIFI_AP_MAX_STA];
17} wifi_sta_list_t;
18
19typedef struct {
20 int num;
21 struct {
22 uint8_t mac[6];
23 esp_ip4_addr_t ip;
24 } sta[ESP_WIFI_AP_MAX_STA];
25} wifi_sta_mac_ip_list_t;
26
27static inline esp_err_t esp_wifi_ap_get_sta_list(wifi_sta_list_t *sta) {
28 memset(sta, 0, sizeof(*sta));
29 return ESP_FAIL;
30}
31
32static inline esp_err_t esp_wifi_ap_get_sta_list_with_ip(const wifi_sta_list_t *sta_in, wifi_sta_mac_ip_list_t *out) {
33 (void)sta_in;
34 memset(out, 0, sizeof(*out));
35 return ESP_FAIL;
36}
37
38#endif
diff --git a/tests/unit/stubs/freertos/task.h b/tests/unit/stubs/freertos/task.h
index 3855d41..ec96156 100644
--- a/tests/unit/stubs/freertos/task.h
+++ b/tests/unit/stubs/freertos/task.h
@@ -6,14 +6,17 @@
6 6
7typedef void *TaskHandle_t; 7typedef void *TaskHandle_t;
8typedef void *SemaphoreHandle_t; 8typedef void *SemaphoreHandle_t;
9typedef int BaseType_t;
10
11#define pdPASS 1
9 12
10static inline void vTaskDelete(TaskHandle_t t) { (void)t; } 13static inline void vTaskDelete(TaskHandle_t t) { (void)t; }
11static inline SemaphoreHandle_t xSemaphoreCreateMutex(void) { return (SemaphoreHandle_t)malloc(1); } 14static inline SemaphoreHandle_t xSemaphoreCreateMutex(void) { return (SemaphoreHandle_t)malloc(1); }
12static inline void vSemaphoreDelete(SemaphoreHandle_t s) { free(s); } 15static inline void vSemaphoreDelete(SemaphoreHandle_t s) { free(s); }
13static inline int xSemaphoreTake(SemaphoreHandle_t s, uint32_t blk) { (void)s; (void)blk; return 1; } 16static inline int xSemaphoreTake(SemaphoreHandle_t s, uint32_t blk) { (void)s; (void)blk; return 1; }
14static inline int xSemaphoreGive(SemaphoreHandle_t s) { (void)s; return 1; } 17static inline int xSemaphoreGive(SemaphoreHandle_t s) { (void)s; return 1; }
15static inline int xTaskCreate(void (*fn)(void*), const char *n, uint32_t st, void *p, uint32_t pri, TaskHandle_t *h) { 18static inline BaseType_t xTaskCreate(void (*fn)(void*), const char *n, uint32_t st, void *p, uint32_t pri, TaskHandle_t *h) {
16 (void)fn; (void)n; (void)st; (void)p; (void)pri; (void)h; return 1; 19 (void)fn; (void)n; (void)st; (void)p; (void)pri; (void)h; return pdPASS;
17} 20}
18 21
19#endif 22#endif
diff --git a/tests/unit/stubs/lwip/etharp.h b/tests/unit/stubs/lwip/etharp.h
new file mode 100644
index 0000000..adc6b7b
--- /dev/null
+++ b/tests/unit/stubs/lwip/etharp.h
@@ -0,0 +1,22 @@
1#ifndef STUBS_LWIP_ETHARP_H
2#define STUBS_LWIP_ETHARP_H
3
4#include <stdint.h>
5#include <stddef.h>
6#include "lwip/ip4_addr.h"
7
8struct eth_addr {
9 uint8_t addr[6];
10};
11
12struct netif;
13
14typedef int err_t;
15#define ERR_OK 0
16
17static inline err_t etharp_get_entry(ssize_t i, ip4_addr_t **ip, struct netif **netif, struct eth_addr **eth) {
18 (void)i; (void)ip; (void)netif; (void)eth;
19 return -1;
20}
21
22#endif
diff --git a/tests/unit/stubs/lwip/ip4_addr.h b/tests/unit/stubs/lwip/ip4_addr.h
index 174211b..9d92ff0 100644
--- a/tests/unit/stubs/lwip/ip4_addr.h
+++ b/tests/unit/stubs/lwip/ip4_addr.h
@@ -3,6 +3,9 @@
3 3
4#include <stdint.h> 4#include <stdint.h>
5 5
6typedef uint32_t u32_t;
7typedef uint16_t u16_t;
8
6typedef struct { 9typedef struct {
7 uint32_t addr; 10 uint32_t addr;
8} ip4_addr_t; 11} ip4_addr_t;
diff --git a/tests/unit/stubs/lwip/napt.h b/tests/unit/stubs/lwip/lwip_napt.h
index c6a5ca1..c6a5ca1 100644
--- a/tests/unit/stubs/lwip/napt.h
+++ b/tests/unit/stubs/lwip/lwip_napt.h
diff --git a/tests/unit/stubs/lwip/netif.h b/tests/unit/stubs/lwip/netif.h
index 461a64e..9415539 100644
--- a/tests/unit/stubs/lwip/netif.h
+++ b/tests/unit/stubs/lwip/netif.h
@@ -1,4 +1,20 @@
1#ifndef STUBS_LWIP_NETIF_H 1#ifndef STUBS_LWIP_NETIF_H
2#define STUBS_LWIP_NETIF_H 2#define STUBS_LWIP_NETIF_H
3 3
4#include <stdint.h>
5#include <stddef.h>
6
7struct pbuf {
8 void *payload;
9 uint16_t len;
10};
11
12static inline uint32_t lwip_ntohl(uint32_t n) {
13 return ((n & 0xFF) << 24) | ((n & 0xFF00) << 8) | ((n >> 8) & 0xFF00) | ((n >> 24) & 0xFF);
14}
15
16static inline uint16_t lwip_ntohs(uint16_t n) {
17 return ((n & 0xFF) << 8) | ((n >> 8) & 0xFF);
18}
19
4#endif 20#endif
diff --git a/tests/unit/stubs/lwip/prot/ip.h b/tests/unit/stubs/lwip/prot/ip.h
new file mode 100644
index 0000000..0770760
--- /dev/null
+++ b/tests/unit/stubs/lwip/prot/ip.h
@@ -0,0 +1,20 @@
1#ifndef STUBS_LWIP_PROT_IP_H
2#define STUBS_LWIP_PROT_IP_H
3
4#include <stdint.h>
5
6#define IP_PROTO_TCP 6
7#define IP_PROTO_UDP 17
8#define IP_HLEN 20
9
10struct ip_hdr {
11 uint8_t _proto;
12 union {
13 uint32_t addr;
14 } src;
15 union {
16 uint32_t addr;
17 } dest;
18};
19
20#endif
diff --git a/tests/unit/stubs/lwip/prot/ip4.h b/tests/unit/stubs/lwip/prot/ip4.h
new file mode 100644
index 0000000..0f70170
--- /dev/null
+++ b/tests/unit/stubs/lwip/prot/ip4.h
@@ -0,0 +1,6 @@
1#ifndef STUBS_LWIP_PROT_IP4_H
2#define STUBS_LWIP_PROT_IP4_H
3
4#include "ip.h"
5
6#endif
diff --git a/tests/unit/stubs/lwip/prot/tcp.h b/tests/unit/stubs/lwip/prot/tcp.h
new file mode 100644
index 0000000..5841371
--- /dev/null
+++ b/tests/unit/stubs/lwip/prot/tcp.h
@@ -0,0 +1,13 @@
1#ifndef STUBS_LWIP_PROT_TCP_H
2#define STUBS_LWIP_PROT_TCP_H
3
4#include <stdint.h>
5
6#define TCP_HLEN 20
7
8struct tcp_hdr {
9 uint16_t src;
10 uint16_t dest;
11};
12
13#endif
diff --git a/tests/unit/stubs/lwip/sockets.h b/tests/unit/stubs/lwip/sockets.h
index 44f03ac..91bf8b2 100644
--- a/tests/unit/stubs/lwip/sockets.h
+++ b/tests/unit/stubs/lwip/sockets.h
@@ -1,4 +1,10 @@
1#ifndef STUBS_LWIP_SOCKETS_H 1#ifndef STUBS_LWIP_SOCKETS_H
2#define STUBS_LWIP_SOCKETS_H 2#define STUBS_LWIP_SOCKETS_H
3 3
4#include <sys/socket.h>
5#include <netinet/in.h>
6#include <arpa/inet.h>
7#include <unistd.h>
8#include <string.h>
9
4#endif 10#endif
diff --git a/tests/unit/test_firewall_sandbox b/tests/unit/test_firewall_sandbox
new file mode 100755
index 0000000..4b85357
--- /dev/null
+++ b/tests/unit/test_firewall_sandbox
Binary files differ
diff --git a/tests/unit/test_firewall_sandbox.c b/tests/unit/test_firewall_sandbox.c
new file mode 100644
index 0000000..66a491b
--- /dev/null
+++ b/tests/unit/test_firewall_sandbox.c
@@ -0,0 +1,94 @@
1#include "test_framework.h"
2#include "../../main/firewall.h"
3#include <stdio.h>
4#include <string.h>
5
6int main(void)
7{
8 printf("=== test_firewall_sandbox ===\n");
9
10 printf("\n--- FW_MAX_MAC_LEN is 18 ---\n");
11 {
12 ASSERT_EQ_INT(18, FW_MAX_MAC_LEN, "MAC length is 18 (17 chars + null)");
13 }
14
15 printf("\n--- esp_ip4_addr_t available ---\n");
16 {
17 esp_ip4_addr_t ip;
18 ip.addr = 0x0102A8C0;
19 ASSERT(ip.addr == 0x0102A8C0, "ip4_addr stores value");
20 }
21
22 printf("\n--- firewall_set_mining_port / set_sandbox_mint_access compile ---\n");
23 {
24 firewall_set_mining_port(3333);
25 firewall_set_mining_port(4033);
26 firewall_set_sandbox_mint_access(true);
27 firewall_set_sandbox_mint_access(false);
28 ASSERT(true, "setters compile and run without crash");
29 }
30
31 printf("\n--- firewall_init + client management ---\n");
32 {
33 esp_ip4_addr_t ap_ip = { .addr = 0x012FA80A };
34 esp_err_t ret = firewall_init(ap_ip);
35 ASSERT_EQ_INT(ESP_OK, (int)ret, "firewall_init succeeds");
36 ASSERT_EQ_INT(0, firewall_client_count(), "no clients after init");
37
38 firewall_grant_access(0x0201A8C0);
39 ASSERT_EQ_INT(1, firewall_client_count(), "1 client after grant");
40 ASSERT(firewall_is_client_allowed(0x0201A8C0), "client is allowed");
41
42 firewall_revoke_access(0x0201A8C0);
43 ASSERT_EQ_INT(0, firewall_client_count(), "0 clients after revoke");
44 ASSERT(!firewall_is_client_allowed(0x0201A8C0), "client not allowed after revoke");
45 }
46
47 printf("\n--- grant same IP twice ---\n");
48 {
49 esp_ip4_addr_t ap_ip = { .addr = 0x012FA80A };
50 firewall_init(ap_ip);
51
52 firewall_grant_access(0x0301A8C0);
53 firewall_grant_access(0x0301A8C0);
54 ASSERT_EQ_INT(1, firewall_client_count(), "duplicate grant does not double count");
55 }
56
57 printf("\n--- revoke non-existent ---\n");
58 {
59 firewall_revoke_access(0x99999999);
60 ASSERT_EQ_INT(1, firewall_client_count(), "revoke non-existent no effect");
61 }
62
63 printf("\n--- revoke_all ---\n");
64 {
65 firewall_grant_access(0x0401A8C0);
66 firewall_grant_access(0x0501A8C0);
67 ASSERT_EQ_INT(3, firewall_client_count(), "3 clients");
68 firewall_revoke_all();
69 ASSERT_EQ_INT(0, firewall_client_count(), "0 after revoke_all");
70 }
71
72 printf("\n--- max clients (10) ---\n");
73 {
74 esp_ip4_addr_t ap_ip = { .addr = 0x012FA80A };
75 firewall_init(ap_ip);
76
77 for (int i = 0; i < 10; i++) {
78 firewall_grant_access(0x0A000000 + i);
79 }
80 ASSERT_EQ_INT(10, firewall_client_count(), "10 clients at max");
81
82 firewall_grant_access(0x0A000100);
83 ASSERT_EQ_INT(10, firewall_client_count(), "still 10 after exceeding max");
84 }
85
86 printf("\n--- is_mac_allowed (no MACs resolved in stub) ---\n");
87 {
88 firewall_init((esp_ip4_addr_t){ .addr = 0x012FA80A });
89 firewall_grant_access(0x0601A8C0);
90 ASSERT(!firewall_is_mac_allowed(""), "empty MAC not allowed");
91 }
92
93 TEST_SUMMARY();
94}
diff --git a/tests/unit/test_identity b/tests/unit/test_identity
index 4dc9cd5..2704601 100755
--- a/tests/unit/test_identity
+++ b/tests/unit/test_identity
Binary files differ
diff --git a/tests/unit/test_mcp_handler b/tests/unit/test_mcp_handler
index b7b1518..be992f6 100755
--- a/tests/unit/test_mcp_handler
+++ b/tests/unit/test_mcp_handler
Binary files differ
diff --git a/tests/unit/test_session_payment_method b/tests/unit/test_session_payment_method
new file mode 100755
index 0000000..94c7134
--- /dev/null
+++ b/tests/unit/test_session_payment_method
Binary files differ
diff --git a/tests/unit/test_session_payment_method.c b/tests/unit/test_session_payment_method.c
new file mode 100644
index 0000000..0239140
--- /dev/null
+++ b/tests/unit/test_session_payment_method.c
@@ -0,0 +1,74 @@
1#include "test_framework.h"
2#include "../../main/session.h"
3#include "../../main/firewall.h"
4#include "../../main/config.h"
5#include "../../main/cashu.h"
6#include <string.h>
7#include <stdio.h>
8
9static tollgate_config_t g_test_config;
10
11const tollgate_config_t *tollgate_config_get(void) {
12 return &g_test_config;
13}
14
15esp_err_t firewall_get_mac_for_ip(uint32_t ip, char *mac_out, size_t size) {
16 (void)ip;
17 snprintf(mac_out, size, "AA:BB:CC:DD:EE:FF");
18 return 0;
19}
20
21static uint32_t g_granted_ips[32];
22static int g_granted_count = 0;
23
24void firewall_grant_access(uint32_t ip) {
25 if (g_granted_count < 32) g_granted_ips[g_granted_count++] = ip;
26}
27
28void firewall_revoke_access(uint32_t ip) {
29 (void)ip;
30}
31
32int main(void)
33{
34 printf("=== test_session_payment_method ===\n");
35 memset(&g_test_config, 0, sizeof(g_test_config));
36 strncpy(g_test_config.metric, "milliseconds", sizeof(g_test_config.metric) - 1);
37 g_granted_count = 0;
38
39 printf("\n--- session_create sets PAYMENT_METHOD_CASHU ---\n");
40 session_manager_init();
41 session_t *s1 = session_create(0x0A010001, 60000);
42 ASSERT(s1 != NULL, "session created");
43 ASSERT_EQ_INT(PAYMENT_METHOD_CASHU, (int)s1->payment_method, "cashu session has PAYMENT_METHOD_CASHU");
44
45 printf("\n--- session_create_bytes sets PAYMENT_METHOD_BYTES ---\n");
46 session_manager_init();
47 g_granted_count = 0;
48 session_t *s2 = session_create_bytes(0x0A010002, 1048576);
49 ASSERT(s2 != NULL, "bytes session created");
50 ASSERT_EQ_INT(PAYMENT_METHOD_BYTES, (int)s2->payment_method, "bytes session has PAYMENT_METHOD_BYTES");
51 ASSERT_EQ_UINT64(1048576, s2->allotment_bytes, "allotment_bytes set");
52 ASSERT_EQ_UINT64(0, s2->bytes_consumed, "bytes_consumed starts at 0");
53
54 printf("\n--- payment_method_t enum values are distinct ---\n");
55 ASSERT(PAYMENT_METHOD_CASHU != PAYMENT_METHOD_MINING, "CASHU != MINING");
56 ASSERT(PAYMENT_METHOD_CASHU != PAYMENT_METHOD_BYTES, "CASHU != BYTES");
57 ASSERT(PAYMENT_METHOD_MINING != PAYMENT_METHOD_BYTES, "MINING != BYTES");
58
59 printf("\n--- session extend preserves payment_method ---\n");
60 session_manager_init();
61 g_granted_count = 0;
62 session_t *s3 = session_create(0x0A010003, 60000);
63 ASSERT_EQ_INT(PAYMENT_METHOD_CASHU, (int)s3->payment_method, "initially CASHU");
64 session_extend(s3, 30000);
65 ASSERT_EQ_INT(PAYMENT_METHOD_CASHU, (int)s3->payment_method, "still CASHU after extend");
66
67 printf("\n--- bytes session allotment_ms is INT64_MAX ---\n");
68 session_manager_init();
69 g_granted_count = 0;
70 session_t *s4 = session_create_bytes(0x0A010004, 2097152);
71 ASSERT(s4->allotment_ms == INT64_MAX, "bytes session has INT64_MAX allotment_ms");
72
73 TEST_SUMMARY();
74}
diff --git a/tests/unit/test_stratum_proxy b/tests/unit/test_stratum_proxy
new file mode 100755
index 0000000..608835f
--- /dev/null
+++ b/tests/unit/test_stratum_proxy
Binary files differ
diff --git a/tests/unit/test_stratum_proxy.c b/tests/unit/test_stratum_proxy.c
new file mode 100644
index 0000000..7788911
--- /dev/null
+++ b/tests/unit/test_stratum_proxy.c
@@ -0,0 +1,95 @@
1#include "test_framework.h"
2#include "../../main/stratum_proxy.h"
3#include "../../main/mining_payment.h"
4#include <stdio.h>
5#include <string.h>
6
7int main(void)
8{
9 printf("=== test_stratum_proxy ===\n");
10
11 mining_payment_init();
12
13 printf("\n--- stratum_proxy_set_job / get_current_job ---\n");
14 {
15 stratum_job_t job = {0};
16 job.job_id = 42;
17 job.nbits = 0x170309E2;
18 job.ntime = 0x6789ABCD;
19 job.version = 0x20000000;
20 job.valid = true;
21 memset(job.prevhash, 0xAA, 32);
22 memset(job.merkle_root, 0xBB, 32);
23
24 stratum_proxy_set_job(&job);
25
26 const stratum_job_t *cur = stratum_proxy_get_current_job();
27 ASSERT(cur != NULL, "current job not NULL");
28 ASSERT_EQ_INT(42, (int)cur->job_id, "job_id=42");
29 ASSERT_EQ_INT(0x170309E2, (int)cur->nbits, "nbits preserved");
30 ASSERT_EQ_INT(0x6789ABCD, (int)cur->ntime, "ntime preserved");
31 ASSERT_EQ_INT(0x20000000, (int)cur->version, "version preserved");
32 ASSERT(cur->valid, "job is valid");
33 ASSERT_MEM_EQ(job.prevhash, cur->prevhash, 32, "prevhash preserved");
34 }
35
36 printf("\n--- stratum_proxy_set_job (NULL) ---\n");
37 {
38 stratum_proxy_set_job(NULL);
39 const stratum_job_t *cur = stratum_proxy_get_current_job();
40 ASSERT_EQ_INT(42, (int)cur->job_id, "job unchanged after NULL set");
41 }
42
43 printf("\n--- stratum_proxy_get_stats ---\n");
44 {
45 mining_set_current_nbits(0x170309E2);
46 stratum_proxy_set_job(&(stratum_job_t){
47 .job_id = 1,
48 .nbits = 0x170309E2,
49 .valid = true
50 });
51
52 stratum_proxy_stats_t stats;
53 memset(&stats, 0xFF, sizeof(stats));
54 stratum_proxy_get_stats(&stats);
55
56 ASSERT(stats.current_hashprice > 0.0, "hashprice populated from mining_payment");
57 ASSERT_EQ_INT(0x170309E2, (int)stats.nbits, "nbits in stats");
58 }
59
60 printf("\n--- stratum_proxy_get_stats (NULL) ---\n");
61 {
62 stratum_proxy_get_stats(NULL);
63 ASSERT(true, "get_stats with NULL does not crash");
64 }
65
66 printf("\n--- stratum_job_t initialization ---\n");
67 {
68 stratum_job_t zero = {0};
69 ASSERT(!zero.valid, "zero-initialized job is invalid");
70 ASSERT_EQ_INT(0, (int)zero.job_id, "zero job_id");
71 ASSERT_EQ_INT(0, (int)zero.nbits, "zero nbits");
72 }
73
74 printf("\n--- stratum_proxy_stats_t initialization ---\n");
75 {
76 stratum_proxy_stats_t zero = {0};
77 ASSERT(zero.hashrate_ghs == 0.0, "zero hashrate");
78 ASSERT_EQ_INT(0, (int)zero.active_miners, "zero active miners");
79 ASSERT_EQ_UINT64(0, zero.total_shares, "zero total shares");
80 ASSERT_EQ_UINT64(0, zero.total_accepted, "zero total accepted");
81 ASSERT_EQ_UINT64(0, zero.total_rejected, "zero total rejected");
82 }
83
84 printf("\n--- STRATUM_MAX_JOBS constant ---\n");
85 {
86 ASSERT(STRATUM_MAX_JOBS >= 1, "STRATUM_MAX_JOBS >= 1");
87 }
88
89 printf("\n--- STRATUM_MAX_JOB_ID_LEN constant ---\n");
90 {
91 ASSERT(STRATUM_MAX_JOB_ID_LEN >= 16, "STRATUM_MAX_JOB_ID_LEN >= 16");
92 }
93
94 TEST_SUMMARY();
95}
diff --git a/tests/unit/test_tollgate_client b/tests/unit/test_tollgate_client
index 02f7226..b56a6f0 100755
--- a/tests/unit/test_tollgate_client
+++ b/tests/unit/test_tollgate_client
Binary files differ
diff --git a/tests/unit/test_tollgate_client_mining b/tests/unit/test_tollgate_client_mining
new file mode 100755
index 0000000..64b99dd
--- /dev/null
+++ b/tests/unit/test_tollgate_client_mining
Binary files differ
diff --git a/tests/unit/test_tollgate_client_mining.c b/tests/unit/test_tollgate_client_mining.c
new file mode 100644
index 0000000..e270864
--- /dev/null
+++ b/tests/unit/test_tollgate_client_mining.c
@@ -0,0 +1,103 @@
1#include "test_framework.h"
2#include "../../main/config.h"
3#include <string.h>
4#include <stdio.h>
5#include <stdlib.h>
6#include <cjson/cJSON.h>
7
8static tollgate_config_t g_test_config;
9
10const tollgate_config_t *tollgate_config_get(void) {
11 return &g_test_config;
12}
13
14uint64_t nucula_wallet_balance(void) { return 100; }
15esp_err_t nucula_wallet_send(uint64_t a, char *b, size_t c) { (void)a; (void)b; (void)c; return ESP_OK; }
16
17#include "freertos/FreeRTOS.h"
18
19#include "../../main/tollgate_client.c"
20
21int main(void)
22{
23 printf("=== test_tollgate_client_mining ===\n");
24
25 memset(&g_test_config, 0, sizeof(g_test_config));
26 g_test_config.client_enabled = true;
27
28 printf("\n--- mining tag: mining_available=true, port=3333 ---\n");
29 {
30 const char *json = "{\"kind\":10021,\"tags\":["
31 "[\"metric\",\"milliseconds\"],"
32 "[\"step_size\",\"60000\"],"
33 "[\"price_per_step\",\"0\",\"mining\",\"3333\",\"sat\"],"
34 "[\"tips\",\"1\",\"2\",\"5\"]"
35 "]}";
36
37 tollgate_discovery_t disc;
38 bool ok = parse_discovery_response(json, &disc);
39 ASSERT(ok, "mining discovery parsed");
40 ASSERT(disc.is_tollgate, "is_tollgate=true");
41 ASSERT(disc.mining_available, "mining_available=true");
42 ASSERT_EQ_INT(3333, (int)disc.mining_port, "mining_port=3333");
43 }
44
45 printf("\n--- mining tag: no mining tag ---\n");
46 {
47 const char *json = "{\"kind\":10021,\"tags\":["
48 "[\"metric\",\"milliseconds\"],"
49 "[\"step_size\",\"60000\"],"
50 "[\"price_per_step\",\"cashu\",\"21\",\"sat\",\"https://testnut.cashu.space\",\"1\"]"
51 "]}";
52
53 tollgate_discovery_t disc;
54 bool ok = parse_discovery_response(json, &disc);
55 ASSERT(ok, "cashu discovery parsed");
56 ASSERT(disc.is_tollgate, "is_tollgate=true");
57 ASSERT(!disc.mining_available, "mining_available=false");
58 ASSERT_EQ_INT(0, (int)disc.mining_port, "mining_port=0 when no mining");
59 ASSERT_EQ_INT(21, disc.price_per_step, "price_per_step=21 for cashu");
60 }
61
62 printf("\n--- mining tag: custom port 4033 ---\n");
63 {
64 const char *json = "{\"kind\":10021,\"tags\":["
65 "[\"metric\",\"milliseconds\"],"
66 "[\"step_size\",\"60000\"],"
67 "[\"price_per_step\",\"0\",\"mining\",\"4033\",\"sat\"]"
68 "]}";
69
70 tollgate_discovery_t disc;
71 bool ok = parse_discovery_response(json, &disc);
72 ASSERT(ok, "mining custom port parsed");
73 ASSERT(disc.mining_available, "mining_available=true");
74 ASSERT_EQ_INT(4033, (int)disc.mining_port, "mining_port=4033");
75 }
76
77 printf("\n--- tollgate_discovery_t zero-init ---\n");
78 {
79 tollgate_discovery_t disc = {0};
80 ASSERT(!disc.is_tollgate, "zero-init: is_tollgate=false");
81 ASSERT(!disc.mining_available, "zero-init: mining_available=false");
82 ASSERT_EQ_INT(0, (int)disc.mining_port, "zero-init: mining_port=0");
83 ASSERT_EQ_INT(0, disc.price_per_step, "zero-init: price=0");
84 }
85
86 printf("\n--- TG_CLIENT_MINING state enum ---\n");
87 {
88 ASSERT(TG_CLIENT_MINING > TG_CLIENT_PAID, "MINING > PAID in enum");
89 ASSERT(TG_CLIENT_MINING < TG_CLIENT_ERROR, "MINING < ERROR in enum");
90 }
91
92 printf("\n--- discovery struct fields ---\n");
93 {
94 tollgate_discovery_t disc;
95 memset(&disc, 0, sizeof(disc));
96 disc.mining_available = true;
97 disc.mining_port = 9999;
98 ASSERT(disc.mining_available, "mining_available set");
99 ASSERT_EQ_INT(9999, (int)disc.mining_port, "mining_port set");
100 }
101
102 TEST_SUMMARY();
103}