honeymaker 0.12.4-aarch64-linux
This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
- checksums.yaml +7 -0
- data/.github/workflows/native-gems.yml +100 -0
- data/.github/workflows/release.yml +36 -0
- data/.github/workflows/test.yml +33 -0
- data/LICENSE +21 -0
- data/README.md +219 -0
- data/Rakefile +78 -0
- data/crates/honeymaker/tests/vectors/decimal.json +146 -0
- data/crates/honeymaker/tests/vectors/kraken_add_order_wire.json +74 -0
- data/crates/honeymaker/tests/vectors/kraken_signing.json +3314 -0
- data/crates/honeymaker/tests/vectors/kraken_trades_pager.json +1583 -0
- data/lib/honeymaker/3.4/honeymaker_native.so +0 -0
- data/lib/honeymaker/4.0/honeymaker_native.so +0 -0
- data/lib/honeymaker/client.rb +139 -0
- data/lib/honeymaker/clients/binance.rb +687 -0
- data/lib/honeymaker/clients/binance_us.rb +42 -0
- data/lib/honeymaker/clients/bingx.rb +242 -0
- data/lib/honeymaker/clients/bitget.rb +318 -0
- data/lib/honeymaker/clients/bitrue.rb +245 -0
- data/lib/honeymaker/clients/bitvavo.rb +244 -0
- data/lib/honeymaker/clients/bybit.rb +308 -0
- data/lib/honeymaker/clients/coinbase.rb +326 -0
- data/lib/honeymaker/clients/gemini.rb +189 -0
- data/lib/honeymaker/clients/hyperliquid.rb +232 -0
- data/lib/honeymaker/clients/kraken.rb +379 -0
- data/lib/honeymaker/clients/kraken_futures.rb +78 -0
- data/lib/honeymaker/clients/kucoin.rb +310 -0
- data/lib/honeymaker/clients/mexc.rb +249 -0
- data/lib/honeymaker/exchange.rb +129 -0
- data/lib/honeymaker/exchanges/binance.rb +55 -0
- data/lib/honeymaker/exchanges/binance_us.rb +9 -0
- data/lib/honeymaker/exchanges/bingx.rb +56 -0
- data/lib/honeymaker/exchanges/bitget.rb +52 -0
- data/lib/honeymaker/exchanges/bitrue.rb +53 -0
- data/lib/honeymaker/exchanges/bitvavo.rb +65 -0
- data/lib/honeymaker/exchanges/bybit.rb +57 -0
- data/lib/honeymaker/exchanges/coinbase.rb +69 -0
- data/lib/honeymaker/exchanges/gemini.rb +134 -0
- data/lib/honeymaker/exchanges/hyperliquid.rb +67 -0
- data/lib/honeymaker/exchanges/kraken.rb +122 -0
- data/lib/honeymaker/exchanges/kucoin.rb +52 -0
- data/lib/honeymaker/exchanges/mexc.rb +56 -0
- data/lib/honeymaker/native/kraken.rb +263 -0
- data/lib/honeymaker/native.rb +42 -0
- data/lib/honeymaker/result.rb +46 -0
- data/lib/honeymaker/utils.rb +39 -0
- data/lib/honeymaker/version.rb +5 -0
- data/lib/honeymaker.rb +97 -0
- data/script/parity/kraken_client_live.rb +191 -0
- data/script/parity/kraken_live.rb +70 -0
- data/script/parity/kraken_transport.rb +604 -0
- data/script/parity/resolve.c +49 -0
- data/script/release/push_gems.sh +28 -0
- data/script/vectors/kraken.rb +50 -0
- data/script/vectors/kraken_stage2.rb +146 -0
- data/sig/honeymaker.rbs +4 -0
- data/test/fixtures/binance_book_ticker.json +7 -0
- data/test/fixtures/binance_exchange_info.json +30 -0
- data/test/fixtures/bingx_symbols.json +26 -0
- data/test/fixtures/bingx_ticker.json +12 -0
- data/test/fixtures/bitget_symbols.json +28 -0
- data/test/fixtures/bitget_tickers.json +14 -0
- data/test/fixtures/bitmart_symbols.json +26 -0
- data/test/fixtures/bitmart_ticker.json +12 -0
- data/test/fixtures/bitrue_book_ticker.json +7 -0
- data/test/fixtures/bitrue_exchange_info.json +34 -0
- data/test/fixtures/bitvavo_book_ticker.json +7 -0
- data/test/fixtures/bitvavo_markets.json +30 -0
- data/test/fixtures/bybit_instruments.json +23 -0
- data/test/fixtures/bybit_tickers.json +19 -0
- data/test/fixtures/coinbase_product.json +7 -0
- data/test/fixtures/coinbase_products.json +24 -0
- data/test/fixtures/gemini_pubticker.json +10 -0
- data/test/fixtures/gemini_symbol_detail.json +10 -0
- data/test/fixtures/gemini_symbols.json +1 -0
- data/test/fixtures/hyperliquid_all_mids.json +5 -0
- data/test/fixtures/hyperliquid_spot_meta.json +12 -0
- data/test/fixtures/kraken_asset_pairs.json +43 -0
- data/test/fixtures/kraken_ticker.json +16 -0
- data/test/fixtures/kucoin_orderbook_level1.json +10 -0
- data/test/fixtures/kucoin_symbols.json +17 -0
- data/test/fixtures/mexc_book_ticker.json +7 -0
- data/test/fixtures/mexc_exchange_info.json +64 -0
- data/test/honeymaker/client_test.rb +90 -0
- data/test/honeymaker/clients/binance_client_test.rb +151 -0
- data/test/honeymaker/clients/binance_us_client_test.rb +25 -0
- data/test/honeymaker/clients/bingx_client_test.rb +106 -0
- data/test/honeymaker/clients/bitget_client_test.rb +146 -0
- data/test/honeymaker/clients/bitrue_client_test.rb +69 -0
- data/test/honeymaker/clients/bitvavo_client_test.rb +156 -0
- data/test/honeymaker/clients/bybit_client_test.rb +137 -0
- data/test/honeymaker/clients/coinbase_client_test.rb +153 -0
- data/test/honeymaker/clients/gemini_client_test.rb +100 -0
- data/test/honeymaker/clients/honeymaker_client_registry_test.rb +39 -0
- data/test/honeymaker/clients/hyperliquid_client_test.rb +292 -0
- data/test/honeymaker/clients/kraken_client_test.rb +255 -0
- data/test/honeymaker/clients/kraken_futures_client_test.rb +54 -0
- data/test/honeymaker/clients/kucoin_client_test.rb +149 -0
- data/test/honeymaker/clients/mexc_client_test.rb +98 -0
- data/test/honeymaker/clients/validation_test.rb +167 -0
- data/test/honeymaker/error_chain_test.rb +133 -0
- data/test/honeymaker/exchange_test.rb +138 -0
- data/test/honeymaker/exchanges/binance_test.rb +83 -0
- data/test/honeymaker/exchanges/binance_us_test.rb +53 -0
- data/test/honeymaker/exchanges/bingx_test.rb +65 -0
- data/test/honeymaker/exchanges/bitget_test.rb +65 -0
- data/test/honeymaker/exchanges/bitrue_test.rb +65 -0
- data/test/honeymaker/exchanges/bitvavo_test.rb +65 -0
- data/test/honeymaker/exchanges/bybit_test.rb +55 -0
- data/test/honeymaker/exchanges/coinbase_test.rb +106 -0
- data/test/honeymaker/exchanges/gemini_catalogue_test.rb +118 -0
- data/test/honeymaker/exchanges/gemini_test.rb +184 -0
- data/test/honeymaker/exchanges/hyperliquid_test.rb +64 -0
- data/test/honeymaker/exchanges/kraken_test.rb +191 -0
- data/test/honeymaker/exchanges/kucoin_test.rb +55 -0
- data/test/honeymaker/exchanges/mexc_test.rb +97 -0
- data/test/honeymaker/honeymaker_test.rb +27 -0
- data/test/honeymaker/result_test.rb +42 -0
- data/test/honeymaker/utils_test.rb +64 -0
- data/test/native/backend_switch_test.rb +53 -0
- data/test/native/convert_test.rb +137 -0
- data/test/native/gem_isolation_test.rb +17 -0
- data/test/native/loader_test.rb +29 -0
- data/test/native/lockstep_test.rb +23 -0
- data/test/native/signing_smoke_test.rb +28 -0
- data/test/parity/kraken_client_parity_test.rb +398 -0
- data/test/parity/kraken_exchange_parity_test.rb +172 -0
- data/test/release/branch_hardening_test.rb +34 -0
- data/test/release/push_gems_test.rb +79 -0
- data/test/smoke.rb +24 -0
- data/test/support/fixture_helper.rb +13 -0
- data/test/support/kraken_signing_smoke.rb +21 -0
- data/test/support/parity_helper.rb +62 -0
- data/test/support/venue_double.rb +100 -0
- data/test/test_helper.rb +9 -0
- metadata +254 -0
|
@@ -0,0 +1,64 @@
|
|
|
1
|
+
# frozen_string_literal: true
|
|
2
|
+
|
|
3
|
+
require "test_helper"
|
|
4
|
+
|
|
5
|
+
class Honeymaker::UtilsTest < Minitest::Test
|
|
6
|
+
def test_decimals_with_string
|
|
7
|
+
assert_equal 2, Honeymaker::Utils.decimals("0.01")
|
|
8
|
+
assert_equal 8, Honeymaker::Utils.decimals("0.00000001")
|
|
9
|
+
assert_equal 1, Honeymaker::Utils.decimals("0.10000000")
|
|
10
|
+
end
|
|
11
|
+
|
|
12
|
+
def test_decimals_with_integer
|
|
13
|
+
assert_equal 0, Honeymaker::Utils.decimals(1)
|
|
14
|
+
assert_equal 0, Honeymaker::Utils.decimals(100)
|
|
15
|
+
end
|
|
16
|
+
|
|
17
|
+
def test_decimals_with_float
|
|
18
|
+
assert_equal 2, Honeymaker::Utils.decimals(0.01)
|
|
19
|
+
assert_equal 1, Honeymaker::Utils.decimals(0.1)
|
|
20
|
+
end
|
|
21
|
+
|
|
22
|
+
def test_decimals_with_no_decimals
|
|
23
|
+
assert_equal 0, Honeymaker::Utils.decimals("1")
|
|
24
|
+
assert_equal 0, Honeymaker::Utils.decimals("10")
|
|
25
|
+
end
|
|
26
|
+
|
|
27
|
+
def test_decimals_with_nil
|
|
28
|
+
assert_equal 0, Honeymaker::Utils.decimals(nil)
|
|
29
|
+
end
|
|
30
|
+
|
|
31
|
+
def test_parse_filters
|
|
32
|
+
filters = [
|
|
33
|
+
{ "filterType" => "PRICE_FILTER", "tickSize" => "0.01" },
|
|
34
|
+
{ "filterType" => "LOT_SIZE", "stepSize" => "0.001" },
|
|
35
|
+
{ "filterType" => "NOTIONAL", "minNotional" => "5" }
|
|
36
|
+
]
|
|
37
|
+
|
|
38
|
+
result = Honeymaker::Utils.parse_filters(filters)
|
|
39
|
+
|
|
40
|
+
assert_equal "0.01", result[:price]["tickSize"]
|
|
41
|
+
assert_equal "0.001", result[:lot_size]["stepSize"]
|
|
42
|
+
assert_equal "5", result[:notional]["minNotional"]
|
|
43
|
+
end
|
|
44
|
+
|
|
45
|
+
def test_parse_filters_with_min_notional
|
|
46
|
+
filters = [
|
|
47
|
+
{ "filterType" => "MIN_NOTIONAL", "minNotional" => "10" }
|
|
48
|
+
]
|
|
49
|
+
|
|
50
|
+
result = Honeymaker::Utils.parse_filters(filters)
|
|
51
|
+
|
|
52
|
+
assert_nil result[:price]
|
|
53
|
+
assert_nil result[:lot_size]
|
|
54
|
+
assert_equal "10", result[:notional]["minNotional"]
|
|
55
|
+
end
|
|
56
|
+
|
|
57
|
+
def test_parse_filters_empty
|
|
58
|
+
result = Honeymaker::Utils.parse_filters([])
|
|
59
|
+
|
|
60
|
+
assert_nil result[:price]
|
|
61
|
+
assert_nil result[:lot_size]
|
|
62
|
+
assert_nil result[:notional]
|
|
63
|
+
end
|
|
64
|
+
end
|
|
@@ -0,0 +1,53 @@
|
|
|
1
|
+
# frozen_string_literal: true
|
|
2
|
+
|
|
3
|
+
require "test_helper"
|
|
4
|
+
require "open3"
|
|
5
|
+
|
|
6
|
+
class Honeymaker::Native::BackendSwitchTest < Minitest::Test
|
|
7
|
+
LIB = File.expand_path("../../lib", __dir__)
|
|
8
|
+
|
|
9
|
+
def ruby(env, code)
|
|
10
|
+
out, status = Open3.capture2e(env, RbConfig.ruby, "-I#{LIB}", "-rbundler/setup", "-e", code)
|
|
11
|
+
[out.strip, status]
|
|
12
|
+
end
|
|
13
|
+
|
|
14
|
+
def test_flag_off_uses_ruby_and_never_loads_the_extension
|
|
15
|
+
out, st = ruby({ "HONEYMAKER_NATIVE" => nil }, <<~RUBY)
|
|
16
|
+
require "honeymaker"
|
|
17
|
+
print [Honeymaker::CLIENTS["kraken"], Honeymaker::EXCHANGES["kraken"], Honeymaker.backend("kraken"),
|
|
18
|
+
$LOADED_FEATURES.grep(/honeymaker_native\\.(so|bundle|dll)\\z/).size].join(",")
|
|
19
|
+
RUBY
|
|
20
|
+
assert st.success?, out
|
|
21
|
+
assert_equal "Honeymaker::Clients::Kraken,Honeymaker::Exchanges::Kraken,ruby,0", out
|
|
22
|
+
end
|
|
23
|
+
|
|
24
|
+
def test_unsupported_flags_fail_at_require_time
|
|
25
|
+
["binance", " kraken, ,binance ", " KRAKEN, bybit "].each do |flag|
|
|
26
|
+
out, st = ruby({ "HONEYMAKER_NATIVE" => flag }, 'require "honeymaker"')
|
|
27
|
+
refute st.success?, out
|
|
28
|
+
assert_match(/unsupported.*(?:binance|bybit)/i, out)
|
|
29
|
+
assert_match(/supported.*kraken/i, out)
|
|
30
|
+
end
|
|
31
|
+
end
|
|
32
|
+
|
|
33
|
+
def test_backend_only_reports_supported_enabled_names
|
|
34
|
+
out, st = ruby({ "HONEYMAKER_NATIVE" => " KRAKEN, ,kraken " }, <<~RUBY)
|
|
35
|
+
require "honeymaker"
|
|
36
|
+
print [Honeymaker.backend(" KRAKEN "), Honeymaker.backend(:binance), Honeymaker.backend("unknown")].join(",")
|
|
37
|
+
RUBY
|
|
38
|
+
assert st.success?, out
|
|
39
|
+
assert_equal "native,ruby,ruby", out
|
|
40
|
+
end
|
|
41
|
+
|
|
42
|
+
def test_flag_on_selects_native_for_kraken_only
|
|
43
|
+
skip "native extension not compiled" unless Dir[File.join(LIB, "honeymaker", "**", "honeymaker_native.{so,bundle,dll}")].any?
|
|
44
|
+
|
|
45
|
+
out, st = ruby({ "HONEYMAKER_NATIVE" => "kraken" }, <<~RUBY)
|
|
46
|
+
require "honeymaker"
|
|
47
|
+
print [Honeymaker.client("kraken").class, Honeymaker.exchange("kraken").class, Honeymaker.backend(:kraken),
|
|
48
|
+
Honeymaker.client("binance").class, $LOADED_FEATURES.grep(/honeymaker_native\\.(so|bundle|dll)\\z/).size].join(",")
|
|
49
|
+
RUBY
|
|
50
|
+
assert st.success?, out
|
|
51
|
+
assert_equal "Honeymaker::Native::KrakenClient,Honeymaker::Native::KrakenExchange,native,Honeymaker::Clients::Binance,1", out
|
|
52
|
+
end
|
|
53
|
+
end
|
|
@@ -0,0 +1,137 @@
|
|
|
1
|
+
# frozen_string_literal: true
|
|
2
|
+
|
|
3
|
+
require "test_helper"
|
|
4
|
+
require "bigdecimal"
|
|
5
|
+
|
|
6
|
+
class Honeymaker::Native::ConvertTest < Minitest::Test
|
|
7
|
+
def setup
|
|
8
|
+
Honeymaker::Native.load!
|
|
9
|
+
rescue LoadError
|
|
10
|
+
raise if ENV["HONEYMAKER_REQUIRE_NATIVE"]
|
|
11
|
+
|
|
12
|
+
skip "native extension not compiled"
|
|
13
|
+
end
|
|
14
|
+
|
|
15
|
+
def ext = Honeymaker::Native::Ext
|
|
16
|
+
|
|
17
|
+
def test_numeric_text_matches_ruby_to_s
|
|
18
|
+
[1.0e-09, -0.0, 0.0, 1.0e20, 1688888888.1234, Float::MIN, Float::MAX,
|
|
19
|
+
Float::INFINITY, -Float::INFINITY, Float::NAN, 12345678901234567890123].each do |value|
|
|
20
|
+
assert_equal value.to_s, ext.to_s_for_tests(value)
|
|
21
|
+
end
|
|
22
|
+
end
|
|
23
|
+
|
|
24
|
+
def test_decimal_json_and_to_s_follow_ruby
|
|
25
|
+
["0.5", 12345678901234567890123, 1.0e-09, -0.0, Float::INFINITY,
|
|
26
|
+
-Float::INFINITY, Float::NAN, nil, true, false, [], { "k" => 1 }].each do |value|
|
|
27
|
+
[true, false].each do |stringify|
|
|
28
|
+
want = (BigDecimal(stringify ? value.to_s : value) rescue $!)
|
|
29
|
+
got = (ext.decimal_convert_for_tests(value, stringify) rescue $!)
|
|
30
|
+
assert_equal want.class, got.class, [value, stringify].inspect
|
|
31
|
+
if want.is_a?(Exception)
|
|
32
|
+
assert_equal want.message, got.message
|
|
33
|
+
else
|
|
34
|
+
assert_equal [want.to_s, want.sign], [got.to_s, got.sign]
|
|
35
|
+
end
|
|
36
|
+
end
|
|
37
|
+
end
|
|
38
|
+
end
|
|
39
|
+
|
|
40
|
+
def test_decimal_arithmetic_survives_gc_in_rust_container
|
|
41
|
+
[["1", "3"], ["-0.0", "2"], ["NaN", "Infinity"], ["1", "0"]].each do |a, b|
|
|
42
|
+
left, right = BigDecimal(a), BigDecimal(b)
|
|
43
|
+
want = [left + right, left - right, left / right]
|
|
44
|
+
GC.stress = true
|
|
45
|
+
got = ext.decimal_arithmetic_for_tests(a, b)
|
|
46
|
+
GC.stress = false
|
|
47
|
+
assert_equal want.map { |n| [n.to_s, n.sign] }, got.take(3).map { |n| [n.to_s, n.sign] }
|
|
48
|
+
assert_equal left.zero?, got[3]
|
|
49
|
+
end
|
|
50
|
+
ensure
|
|
51
|
+
GC.stress = false
|
|
52
|
+
end
|
|
53
|
+
|
|
54
|
+
def test_non_utf8_strings_roundtrip_with_bytes_and_encoding
|
|
55
|
+
["O\xff", "O\xff".b, "é".b, "é".encode("ISO-8859-1")].each do |value|
|
|
56
|
+
got = ext.roundtrip_for_tests([value]).first
|
|
57
|
+
assert_equal value.bytes, got.bytes
|
|
58
|
+
assert_equal value.encoding, got.encoding
|
|
59
|
+
end
|
|
60
|
+
end
|
|
61
|
+
|
|
62
|
+
def test_invalid_string_hash_keys_roundtrip
|
|
63
|
+
["O\xff", "O\xff".b, "é".b].each do |key|
|
|
64
|
+
got = ext.roundtrip_for_tests({ key => "value" }).keys.first
|
|
65
|
+
assert_equal key.bytes, got.bytes
|
|
66
|
+
assert_equal key.encoding, got.encoding
|
|
67
|
+
end
|
|
68
|
+
end
|
|
69
|
+
|
|
70
|
+
def test_internal_string_sentinel_names_are_ordinary_hash_keys
|
|
71
|
+
obj = { "\0ruby_string" => [[], "UTF-8"], "\0ruby_key:\"literal\"" => "value" }
|
|
72
|
+
assert_equal obj, ext.roundtrip_for_tests(obj)
|
|
73
|
+
assert_equal({ "\0ruby_string" => [[], "UTF-8"] }, ext.roundtrip_for_tests({ "\0ruby_string" => [[], "UTF-8"] }))
|
|
74
|
+
end
|
|
75
|
+
|
|
76
|
+
def test_invalid_decimal_strings_use_rubys_own_errors
|
|
77
|
+
["1\xff", "1\xff".b].each do |value|
|
|
78
|
+
[true, false].each do |stringify|
|
|
79
|
+
want = (BigDecimal(value) rescue $!)
|
|
80
|
+
got = (ext.decimal_convert_for_tests(value, stringify) rescue $!)
|
|
81
|
+
assert_equal [want.class, want.message], [got.class, got.message]
|
|
82
|
+
end
|
|
83
|
+
end
|
|
84
|
+
end
|
|
85
|
+
|
|
86
|
+
def test_shape_errors
|
|
87
|
+
error = assert_raises(Honeymaker::Native::ShapeError) { ext.roundtrip_for_tests({ key: 1 }) }
|
|
88
|
+
assert_equal "non-string key", error.message
|
|
89
|
+
error = assert_raises(Honeymaker::Native::ShapeError) { ext.roundtrip_for_tests(:unsupported) }
|
|
90
|
+
assert_equal "unsupported value :unsupported", error.message
|
|
91
|
+
end
|
|
92
|
+
|
|
93
|
+
def test_false_negative_infinity_nan_and_negative_zero
|
|
94
|
+
got = ext.roundtrip_for_tests([false, -Float::INFINITY, Float::NAN, -0.0])
|
|
95
|
+
assert_equal false, got[0]
|
|
96
|
+
assert_equal(-Float::INFINITY, got[1])
|
|
97
|
+
assert_predicate got[2], :nan?
|
|
98
|
+
assert_equal(-Float::INFINITY, 1.0 / got[3])
|
|
99
|
+
end
|
|
100
|
+
|
|
101
|
+
def test_json_roundtrip_is_exact
|
|
102
|
+
obj = JSON.parse('{"i":12345678901234567890123,"f":1688888888.1234,"e":1e-09,"z":-0.0,"s":"\u00e9","n":null,' \
|
|
103
|
+
'"b":true,"a":[1,2.5,"x"],"big":1e400,"o":{"k":{"k2":[]}}}')
|
|
104
|
+
got = ext.roundtrip_for_tests(obj)
|
|
105
|
+
assert_equal obj.keys, got.keys
|
|
106
|
+
obj.keys.each do |k|
|
|
107
|
+
v = obj[k]
|
|
108
|
+
assert_equal v.class, got[k].class, k
|
|
109
|
+
assert(v.is_a?(Float) ? v.eql?(got[k]) : v == got[k], k)
|
|
110
|
+
end
|
|
111
|
+
assert_equal Encoding::UTF_8, got["s"].encoding
|
|
112
|
+
end
|
|
113
|
+
|
|
114
|
+
def test_decimal_is_rubys_own
|
|
115
|
+
["0.5", "-0.0000", "NaN", "Infinity", "1_000", "1e-9"].each do |s|
|
|
116
|
+
want = BigDecimal(s)
|
|
117
|
+
got = ext.decimal_for_tests(s)
|
|
118
|
+
assert_equal [want.to_s, want.sign], [got.to_s, got.sign], s
|
|
119
|
+
end
|
|
120
|
+
["", "abc", "true", "[]", "{}"].each do |s|
|
|
121
|
+
want = (BigDecimal(s) rescue $!)
|
|
122
|
+
got = (ext.decimal_for_tests(s) rescue $!)
|
|
123
|
+
assert_equal [want.class, want.message], [got.class, got.message], s.inspect
|
|
124
|
+
end
|
|
125
|
+
end
|
|
126
|
+
|
|
127
|
+
def test_survives_gc_stress_and_compaction
|
|
128
|
+
obj = JSON.parse({ "rows" => (1..2_000).map { |i| { "id" => "O#{i}", "vol" => "0.#{i}", "t" => i + 0.5 } } }.to_json)
|
|
129
|
+
GC.stress = true
|
|
130
|
+
got = ext.roundtrip_for_tests(obj)
|
|
131
|
+
GC.stress = false
|
|
132
|
+
GC.compact if GC.respond_to?(:compact)
|
|
133
|
+
assert_equal obj, got
|
|
134
|
+
ensure
|
|
135
|
+
GC.stress = false
|
|
136
|
+
end
|
|
137
|
+
end
|
|
@@ -0,0 +1,17 @@
|
|
|
1
|
+
# frozen_string_literal: true
|
|
2
|
+
|
|
3
|
+
require "test_helper"
|
|
4
|
+
require "open3"
|
|
5
|
+
|
|
6
|
+
# Spec §2.2: the platform gems cross-compile with nothing but pure-Rust crypto. The async client
|
|
7
|
+
# lives in the same Cargo workspace, so this proves the extension never pulls it in.
|
|
8
|
+
class Honeymaker::Native::GemIsolationTest < Minitest::Test
|
|
9
|
+
FORBIDDEN = /\A(tokio|tokio-rustls|hyper|hyper-util|rustls|ring|aws-lc-rs|aws-lc-sys|webpki-roots|honeymaker-client) /
|
|
10
|
+
|
|
11
|
+
def test_the_extension_does_not_depend_on_the_async_client_stack
|
|
12
|
+
out, status = Open3.capture2("cargo", "tree", "--locked", "-p", "honeymaker_native", "-e", "normal,build",
|
|
13
|
+
"--prefix", "none", chdir: File.expand_path("../..", __dir__))
|
|
14
|
+
assert status.success?, "cargo tree failed"
|
|
15
|
+
assert_empty out.lines.grep(FORBIDDEN).uniq
|
|
16
|
+
end
|
|
17
|
+
end
|
|
@@ -0,0 +1,29 @@
|
|
|
1
|
+
# frozen_string_literal: true
|
|
2
|
+
|
|
3
|
+
require "test_helper"
|
|
4
|
+
|
|
5
|
+
class Honeymaker::Native::LoaderTest < Minitest::Test
|
|
6
|
+
def setup
|
|
7
|
+
Honeymaker::Native.load!
|
|
8
|
+
rescue LoadError => e
|
|
9
|
+
raise if ENV["HONEYMAKER_REQUIRE_NATIVE"]
|
|
10
|
+
|
|
11
|
+
skip "native extension not compiled (#{e.message})"
|
|
12
|
+
end
|
|
13
|
+
|
|
14
|
+
def test_extension_reports_the_gem_version
|
|
15
|
+
assert_equal Honeymaker::VERSION, Honeymaker::Native::Ext.version
|
|
16
|
+
end
|
|
17
|
+
|
|
18
|
+
def test_flag_parsing
|
|
19
|
+
Honeymaker::Native.instance_variable_set(:@enabled, nil)
|
|
20
|
+
ENV["HONEYMAKER_NATIVE"] = " KRAKEN, ,kraken "
|
|
21
|
+
assert_equal %w[kraken], Honeymaker::Native.enabled
|
|
22
|
+
assert Honeymaker::Native.enabled?(:kraken)
|
|
23
|
+
assert Honeymaker::Native.enabled?(" KRAKEN ")
|
|
24
|
+
refute Honeymaker::Native.enabled?("bybit")
|
|
25
|
+
ensure
|
|
26
|
+
ENV.delete("HONEYMAKER_NATIVE")
|
|
27
|
+
Honeymaker::Native.instance_variable_set(:@enabled, nil)
|
|
28
|
+
end
|
|
29
|
+
end
|
|
@@ -0,0 +1,23 @@
|
|
|
1
|
+
# frozen_string_literal: true
|
|
2
|
+
|
|
3
|
+
require "test_helper"
|
|
4
|
+
require "tmpdir"
|
|
5
|
+
|
|
6
|
+
class Honeymaker::Native::LockstepTest < Minitest::Test
|
|
7
|
+
def test_cargo_workspace_version_equals_gem_version
|
|
8
|
+
cargo = File.read(File.expand_path("../../Cargo.toml", __dir__))
|
|
9
|
+
assert_equal Honeymaker::VERSION, cargo[/^\[workspace\.package\].*?^version = "([^"]+)"/m, 1]
|
|
10
|
+
end
|
|
11
|
+
|
|
12
|
+
def test_bump_updates_cargo_too
|
|
13
|
+
rakefile = File.expand_path("../../Rakefile", __dir__)
|
|
14
|
+
Dir.mktmpdir do |dir|
|
|
15
|
+
FileUtils.mkdir_p(File.join(dir, "lib/honeymaker"))
|
|
16
|
+
File.write(File.join(dir, "lib/honeymaker/version.rb"), %(module Honeymaker\n VERSION = "1.2.3"\nend\n))
|
|
17
|
+
File.write(File.join(dir, "Cargo.toml"), %([workspace]\nmembers = []\n\n[workspace.package]\nversion = "1.2.3" # c\n))
|
|
18
|
+
out = Dir.chdir(dir) { `HONEYMAKER_RAKEFILE_LIB_ONLY=1 #{RbConfig.ruby} -rrake -e 'load "#{rakefile}"; bump_version(:minor)' 2>&1` }
|
|
19
|
+
assert_includes out, "1.3.0"
|
|
20
|
+
assert_includes File.read(File.join(dir, "Cargo.toml")), %(version = "1.3.0" # c)
|
|
21
|
+
end
|
|
22
|
+
end
|
|
23
|
+
end
|
|
@@ -0,0 +1,28 @@
|
|
|
1
|
+
# frozen_string_literal: true
|
|
2
|
+
|
|
3
|
+
require "test_helper"
|
|
4
|
+
|
|
5
|
+
class KrakenSigningSmokeTest < Minitest::Test
|
|
6
|
+
def setup
|
|
7
|
+
Honeymaker::Native.load!
|
|
8
|
+
require_relative "../support/kraken_signing_smoke"
|
|
9
|
+
rescue LoadError => e
|
|
10
|
+
raise if ENV["HONEYMAKER_REQUIRE_NATIVE"]
|
|
11
|
+
|
|
12
|
+
skip e.message
|
|
13
|
+
end
|
|
14
|
+
|
|
15
|
+
def test_real_signing_vector
|
|
16
|
+
assert KrakenSigningSmoke.verify!
|
|
17
|
+
end
|
|
18
|
+
|
|
19
|
+
def test_rejects_incorrect_key_or_signature
|
|
20
|
+
vector = JSON.parse(File.read(KrakenSigningSmoke::VECTORS)).find { |v| !v.fetch("api_key").empty? && !v.fetch("api_secret").empty? }
|
|
21
|
+
%w[API-Key API-Sign].each do |field|
|
|
22
|
+
signer = stub(sign: vector.fetch("headers").merge(field => "wrong"))
|
|
23
|
+
Honeymaker::Native::Ext::Kraken.stubs(:new).with(vector.fetch("api_key"), vector.fetch("api_secret")).returns(signer)
|
|
24
|
+
_, stderr = capture_io { assert_raises(SystemExit) { KrakenSigningSmoke.verify! } }
|
|
25
|
+
assert_match(/#{field}/, stderr)
|
|
26
|
+
end
|
|
27
|
+
end
|
|
28
|
+
end
|