2022-09-28 18:47:15 +00:00
|
|
|
# beacon_chain
|
2024-01-06 14:26:56 +00:00
|
|
|
# Copyright (c) 2021-2024 Status Research & Development GmbH
|
2022-09-28 18:47:15 +00:00
|
|
|
# Licensed and distributed under either of
|
|
|
|
# * MIT license (license terms in the root directory or at https://opensource.org/licenses/MIT).
|
|
|
|
# * Apache v2 license (license terms in the root directory or at https://www.apache.org/licenses/LICENSE-2.0).
|
|
|
|
# at your option. This file may not be copied, modified, or distributed except according to those terms.
|
|
|
|
|
2024-02-29 13:24:08 +00:00
|
|
|
{.push raises: [].}
|
2022-09-28 18:47:15 +00:00
|
|
|
{.used.}
|
|
|
|
|
|
|
|
import
|
2024-06-11 02:34:56 +00:00
|
|
|
presto/client,
|
2022-09-28 18:47:15 +00:00
|
|
|
testutils/unittests, chronicles,
|
|
|
|
../beacon_chain/spec/eth2_apis/[eth2_rest_serialization, rest_types],
|
|
|
|
./testutil
|
|
|
|
|
|
|
|
suite "Serialization/deserialization test suite":
|
2022-09-29 20:55:18 +00:00
|
|
|
test "RestErrorMessage parser tests":
|
2022-09-28 18:47:15 +00:00
|
|
|
const GoodTestVectors = [
|
|
|
|
(
|
|
|
|
"""{"code": 500, "message": "block not found"}""",
|
2022-09-29 20:55:18 +00:00
|
|
|
RestErrorMessage.init(500, "block not found")
|
2022-09-28 18:47:15 +00:00
|
|
|
),
|
|
|
|
(
|
|
|
|
"""{"code": "600", "message": "block not found"}""",
|
2022-09-29 20:55:18 +00:00
|
|
|
RestErrorMessage.init(600, "block not found")
|
2022-09-28 18:47:15 +00:00
|
|
|
),
|
|
|
|
(
|
|
|
|
"""{"code": "700", "message": "block not found",
|
|
|
|
"data": "data", "custom": "field"}""",
|
2022-09-29 20:55:18 +00:00
|
|
|
RestErrorMessage.init(700, "block not found")
|
2022-09-28 18:47:15 +00:00
|
|
|
),
|
|
|
|
(
|
|
|
|
"""{"code":"701", "message": "block not found",
|
|
|
|
"data": "data", "custom": 300}""",
|
2022-09-29 20:55:18 +00:00
|
|
|
RestErrorMessage.init(701, "block not found")
|
2022-09-28 18:47:15 +00:00
|
|
|
),
|
|
|
|
(
|
|
|
|
"""{"code": "702", "message": "block not found",
|
|
|
|
"data": "data", "custom": {"field1": "value1"}}""",
|
2022-09-29 20:55:18 +00:00
|
|
|
RestErrorMessage.init(702, "block not found")
|
2022-09-28 18:47:15 +00:00
|
|
|
),
|
|
|
|
(
|
|
|
|
"""{"code": 800, "message": "block not found",
|
|
|
|
"custom": "data", "stacktraces": []}""",
|
2022-09-29 20:55:18 +00:00
|
|
|
RestErrorMessage.init(800, "block not found", [])
|
2022-09-28 18:47:15 +00:00
|
|
|
),
|
|
|
|
(
|
|
|
|
"""{"code": 801, "message": "block not found",
|
|
|
|
"custom": 100, "stacktraces": []}""",
|
2022-09-29 20:55:18 +00:00
|
|
|
RestErrorMessage.init(801, "block not found", [])
|
2022-09-28 18:47:15 +00:00
|
|
|
),
|
|
|
|
(
|
|
|
|
"""{"code": 802, "message": "block not found",
|
|
|
|
"custom": {"field1": "value1"}, "stacktraces": []}""",
|
2022-09-29 20:55:18 +00:00
|
|
|
RestErrorMessage.init(802, "block not found", [])
|
2022-09-28 18:47:15 +00:00
|
|
|
),
|
|
|
|
(
|
|
|
|
"""{"code": "900", "message": "block not found",
|
|
|
|
"stacktraces": ["line1", "line2", "line3"], "custom": "data"}""",
|
2022-09-29 20:55:18 +00:00
|
|
|
RestErrorMessage.init(900, "block not found",
|
2022-09-28 18:47:15 +00:00
|
|
|
["line1", "line2", "line3"])
|
|
|
|
),
|
|
|
|
(
|
|
|
|
"""{"code": "901", "message": "block not found",
|
|
|
|
"stacktraces": ["line1", "line2", "line3"], "custom": 2000}""",
|
2022-09-29 20:55:18 +00:00
|
|
|
RestErrorMessage.init(901, "block not found",
|
2022-09-28 18:47:15 +00:00
|
|
|
["line1", "line2", "line3"])
|
|
|
|
),
|
|
|
|
(
|
|
|
|
"""{"code": "902", "message": "block not found",
|
|
|
|
"stacktraces": ["line1", "line2", "line3"],
|
|
|
|
"custom": {"field1": "value1"}}""",
|
2022-09-29 20:55:18 +00:00
|
|
|
RestErrorMessage.init(902, "block not found",
|
2022-09-28 18:47:15 +00:00
|
|
|
["line1", "line2", "line3"])
|
|
|
|
)
|
|
|
|
]
|
|
|
|
|
|
|
|
const FailureTestVectors = [
|
|
|
|
# `code` has negative value.
|
|
|
|
"""{"code":-1, "message": "block not found"}""",
|
|
|
|
# `code` has negative value encoded as string.
|
|
|
|
"""{"code": "-1", "message": "block not found"}""",
|
|
|
|
# `code` field as an object.
|
|
|
|
"""{"code":{"object": "value"}, "message": "block not found"}""",
|
|
|
|
# `message` field as number.
|
|
|
|
"""{"code": "400", "message": 100}""",
|
|
|
|
# `message` field as an object.
|
|
|
|
"""{"code": "400", "message": {"object": "value"}}""",
|
|
|
|
# `stacktraces` field as an object.
|
|
|
|
"""{"code": "400", "message": "block not found",
|
|
|
|
"stacktraces":{"object": "value"}}""",
|
|
|
|
# Field `stacktraces` mixed array values.
|
|
|
|
"""{"code": "400", "message": "block not found",
|
|
|
|
"stacktraces":["object", 1]""",
|
|
|
|
# missing required field `code` and `message`.
|
|
|
|
"",
|
|
|
|
# missing required field `message`.
|
|
|
|
"""{"code":"400"}""",
|
|
|
|
# missing required field `code`.
|
|
|
|
"""{"message": "block not found"}"""
|
|
|
|
]
|
|
|
|
|
|
|
|
let contentType = getContentType("application/json").get()
|
|
|
|
|
|
|
|
for test in GoodTestVectors:
|
|
|
|
let res = decodeBytes(
|
2022-09-29 20:55:18 +00:00
|
|
|
RestErrorMessage, test[0].toOpenArrayByte(0, len(test[0]) - 1),
|
2022-09-28 18:47:15 +00:00
|
|
|
Opt.some(contentType))
|
|
|
|
check res.isOk()
|
|
|
|
let response = res.get()
|
|
|
|
check:
|
|
|
|
response.code == test[1].code
|
|
|
|
response.message == test[1].message
|
|
|
|
if response.stacktraces.isNone():
|
|
|
|
check test[1].stacktraces.isNone()
|
|
|
|
else:
|
|
|
|
check:
|
|
|
|
test[1].stacktraces.isSome()
|
|
|
|
test[1].stacktraces.get() == response.stacktraces.get()
|
|
|
|
|
|
|
|
for test in FailureTestVectors:
|
|
|
|
let res = decodeBytes(
|
2022-09-29 20:55:18 +00:00
|
|
|
RestErrorMessage, test.toOpenArrayByte(0, len(test) - 1),
|
2022-09-28 18:47:15 +00:00
|
|
|
Opt.some(contentType))
|
2022-09-29 20:55:18 +00:00
|
|
|
checkpoint test
|
2022-09-28 18:47:15 +00:00
|
|
|
check res.isErr()
|
2023-09-27 14:45:33 +00:00
|
|
|
|
2022-09-29 20:55:18 +00:00
|
|
|
test "RestErrorMessage writer tests":
|
2022-09-28 18:47:15 +00:00
|
|
|
proc `==`(a: RestApiResponse, b: string): bool =
|
|
|
|
case a.kind
|
|
|
|
of RestApiResponseKind.Content:
|
|
|
|
a.content.data.bytesToString() == b
|
|
|
|
of RestApiResponseKind.Error:
|
|
|
|
a.errobj.message == b
|
|
|
|
else:
|
|
|
|
raiseAssert "Unsupported RestApiResponse kind"
|
|
|
|
check:
|
|
|
|
jsonMsgResponse(RestApiResponse, "data") ==
|
|
|
|
"""{"code":200,"message":"data"}"""
|
|
|
|
jsonError(RestApiResponse, Http202, "data") ==
|
|
|
|
"""{"code":202,"message":"data"}"""
|
|
|
|
jsonError(RestApiResponse, Http400, "data", "") ==
|
|
|
|
"""{"code":400,"message":"data"}"""
|
|
|
|
jsonError(RestApiResponse, Http404, "data", "stacktrace") ==
|
|
|
|
"""{"code":404,"message":"data","stacktraces":["stacktrace"]}"""
|
|
|
|
jsonError(RestApiResponse, Http500, "data", ["s1", "s2"]) ==
|
|
|
|
"""{"code":500,"message":"data","stacktraces":["s1","s2"]}"""
|
|
|
|
jsonErrorList(RestApiResponse, Http408, "data", ["s1", "s2"]) ==
|
|
|
|
"""{"code":408,"message":"data","failures":["s1","s2"]}"""
|
2023-11-28 23:30:14 +00:00
|
|
|
|
|
|
|
test "strictParse(Stuint) tests":
|
|
|
|
const
|
|
|
|
GoodVectors16 = [
|
|
|
|
("FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF",
|
|
|
|
"ffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff"),
|
|
|
|
("0xFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF",
|
|
|
|
"ffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff"),
|
|
|
|
("0x123456789ABCDEFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF",
|
|
|
|
"123456789abcdefffffffffffffffffffffffffffffffffffffffffffffffff"),
|
|
|
|
("123456789ABCDEFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF",
|
|
|
|
"123456789abcdefffffffffffffffffffffffffffffffffffffffffffffffff")
|
|
|
|
]
|
|
|
|
GoodVectors10 = [
|
|
|
|
("115792089237316195423570985008687907853269984665640564039457584007913129639935",
|
|
|
|
"ffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff"),
|
|
|
|
("0", "0"),
|
|
|
|
]
|
|
|
|
GoodVectors8 = [
|
|
|
|
("0o17777777777777777777777777777777777777777777777777777777777777777777777777777777777777",
|
|
|
|
"ffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff")
|
|
|
|
]
|
|
|
|
GoodVectors2 = [
|
|
|
|
("0b1111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111",
|
|
|
|
"ffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff")
|
|
|
|
]
|
|
|
|
OverflowVectors16 = [
|
|
|
|
"FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF0",
|
|
|
|
"FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFE",
|
|
|
|
"0xFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF0",
|
|
|
|
"0xFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFE"
|
|
|
|
]
|
|
|
|
OverflowVectors10 = [
|
|
|
|
"1157920892373161954235709850086879078532699846656405640394575840079131296399350",
|
|
|
|
"1157920892373161954235709850086879078532699846656405640394575840079131296399351"
|
|
|
|
]
|
|
|
|
OverflowVectors8 = [
|
|
|
|
"0o177777777777777777777777777777777777777777777777777777777777777777777777777777777777770",
|
|
|
|
"0o177777777777777777777777777777777777777777777777777777777777777777777777777777777777777"
|
|
|
|
]
|
|
|
|
OverflowVectors2 = [
|
|
|
|
"0b11111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111110",
|
|
|
|
"0b11111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111"
|
|
|
|
]
|
|
|
|
InvalidCharsVectors16 = [
|
|
|
|
"GFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF",
|
|
|
|
"0xGFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF",
|
|
|
|
"0x0123456789ABCDEFZFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF",
|
|
|
|
"0123456789ABCDEFXFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF"
|
|
|
|
]
|
|
|
|
InvalidCharsVectors10 = [
|
|
|
|
"11579208923731619542357098500868790785326998466564056403945758400791312963993A",
|
|
|
|
"K"
|
|
|
|
]
|
|
|
|
InvalidCharsVectors8 = [
|
|
|
|
"0o17777777777777777777777777777777777777777777777777777777777777777777777777777777777778"
|
|
|
|
]
|
|
|
|
InvalidCharsVectors2 = [
|
|
|
|
"0b1111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111112"
|
|
|
|
]
|
|
|
|
|
|
|
|
for vector in GoodVectors16:
|
|
|
|
let res = strictParse(vector[0], UInt256, 16)
|
|
|
|
check:
|
|
|
|
res.isOk()
|
|
|
|
res.get().toHex() == vector[1]
|
|
|
|
|
|
|
|
for vector in GoodVectors10:
|
|
|
|
let res = strictParse(vector[0], UInt256, 10)
|
|
|
|
check:
|
|
|
|
res.isOk()
|
|
|
|
res.get().toHex() == vector[1]
|
|
|
|
|
|
|
|
for vector in GoodVectors8:
|
|
|
|
let res = strictParse(vector[0], UInt256, 8)
|
|
|
|
check:
|
|
|
|
res.isOk()
|
|
|
|
res.get().toHex() == vector[1]
|
|
|
|
|
|
|
|
for vector in GoodVectors2:
|
|
|
|
let res = strictParse(vector[0], UInt256, 2)
|
|
|
|
check:
|
|
|
|
res.isOk()
|
|
|
|
res.get().toHex() == vector[1]
|
|
|
|
|
|
|
|
for vector in OverflowVectors16:
|
|
|
|
let res = strictParse(vector, UInt256, 16)
|
|
|
|
check:
|
|
|
|
res.isErr()
|
|
|
|
res.error == "Overflow error"
|
|
|
|
|
|
|
|
for vector in OverflowVectors10:
|
|
|
|
let res = strictParse(vector, UInt256, 10)
|
|
|
|
check:
|
|
|
|
res.isErr()
|
|
|
|
res.error == "Overflow error"
|
|
|
|
|
|
|
|
for vector in OverflowVectors8:
|
|
|
|
let res = strictParse(vector, UInt256, 8)
|
|
|
|
check:
|
|
|
|
res.isErr()
|
|
|
|
res.error == "Overflow error"
|
|
|
|
|
|
|
|
for vector in OverflowVectors2:
|
|
|
|
let res = strictParse(vector, UInt256, 2)
|
|
|
|
check:
|
|
|
|
res.isErr()
|
|
|
|
res.error == "Overflow error"
|
|
|
|
|
|
|
|
for vector in InvalidCharsVectors16:
|
|
|
|
let res = strictParse(vector, UInt256, 16)
|
|
|
|
check res.isErr()
|
|
|
|
|
|
|
|
for vector in InvalidCharsVectors10:
|
|
|
|
let res = strictParse(vector, UInt256, 10)
|
|
|
|
check res.isErr()
|
|
|
|
|
|
|
|
for vector in InvalidCharsVectors8:
|
|
|
|
let res = strictParse(vector, UInt256, 8)
|
|
|
|
check res.isErr()
|
|
|
|
|
|
|
|
for vector in InvalidCharsVectors2:
|
|
|
|
let res = strictParse(vector, UInt256, 2)
|
|
|
|
check res.isErr()
|