From cf940a269ae28b6bfd12dca5881b2d93d5b21295 Mon Sep 17 00:00:00 2001 From: refring Date: Sat, 6 Dec 2025 14:11:51 +0100 Subject: [PATCH 1/2] chore: Updated monero version to 0.18.4.4 for tests --- .github/workflows/tests.yml | 2 +- tests/docker-compose.yml | 8 ++++---- 2 files changed, 5 insertions(+), 5 deletions(-) diff --git a/.github/workflows/tests.yml b/.github/workflows/tests.yml index e26e929..43bf927 100644 --- a/.github/workflows/tests.yml +++ b/.github/workflows/tests.yml @@ -64,7 +64,7 @@ jobs: - name: Spin up containers run: docker compose -f tests/docker-compose.yml up -d env: - MONERO_VERSION: "0.18.4.0" + MONERO_VERSION: "0.18.4.4" - name: Install PHP uses: shivammathur/setup-php@v2 diff --git a/tests/docker-compose.yml b/tests/docker-compose.yml index d0582c4..c7dfaa0 100644 --- a/tests/docker-compose.yml +++ b/tests/docker-compose.yml @@ -1,6 +1,6 @@ services: monerod: - image: ghcr.io/refring/monero-containers/monerod:${MONERO_VERSION:-0.18.4.0} + image: ghcr.io/refring/monero-containers/monerod:${MONERO_VERSION:-0.18.4.4} environment: NETWORK: regtest MONEROD_RPC_PORT: 18081 @@ -11,7 +11,7 @@ services: - "18081:18081" monero-wallet-rpc: - image: ghcr.io/refring/monero-containers/monero-wallet-rpc:${MONERO_VERSION:-0.18.4.0} + image: ghcr.io/refring/monero-containers/monero-wallet-rpc:${MONERO_VERSION:-0.18.4.4} environment: MONERO_DAEMON_ADDRESS: monerod:18081 MONERO_DAEMON_HOST: monerod:18081 @@ -22,7 +22,7 @@ services: - "18083:18083" monerod-rpc-authentication: - image: ghcr.io/refring/monero-containers/monerod:${MONERO_VERSION:-0.18.4.0} + image: ghcr.io/refring/monero-containers/monerod:${MONERO_VERSION:-0.18.4.4} depends_on: - "monerod" ports: @@ -38,7 +38,7 @@ services: --fixed-difficulty 1 monero-wallet-rpc-authentication: - image: ghcr.io/refring/monero-containers/monero-wallet-rpc:${MONERO_VERSION:-0.18.4.0} + image: ghcr.io/refring/monero-containers/monero-wallet-rpc:${MONERO_VERSION:-0.18.4.4} depends_on: - "monerod" ports: From d31744a449c66db71af5a7fb17f89fd78e4d14c3 Mon Sep 17 00:00:00 2001 From: refring Date: Sat, 6 Dec 2025 19:18:15 +0100 Subject: [PATCH 2/2] feat: Some tests would fail on older versions of the json-rpc api, allow tests to only run on specific versions through an attribute --- tests/Attribute/RequiresMoneroVersion.php | 25 ++++++++ tests/Trait/RequiresMoneroVersionTrait.php | 70 ++++++++++++++++++++++ tests/integration/DaemonTest.php | 30 +++++++--- tests/unit/RequiresMoneroVersionTest.php | 35 +++++++++++ 4 files changed, 152 insertions(+), 8 deletions(-) create mode 100644 tests/Attribute/RequiresMoneroVersion.php create mode 100644 tests/Trait/RequiresMoneroVersionTrait.php create mode 100644 tests/unit/RequiresMoneroVersionTest.php diff --git a/tests/Attribute/RequiresMoneroVersion.php b/tests/Attribute/RequiresMoneroVersion.php new file mode 100644 index 0000000..9b725d0 --- /dev/null +++ b/tests/Attribute/RequiresMoneroVersion.php @@ -0,0 +1,25 @@ +version) + */ +#[Attribute(Attribute::TARGET_METHOD | Attribute::TARGET_CLASS)] +final class RequiresMoneroVersion +{ + public function __construct( + public readonly string $minVersion, + public readonly ?string $maxVersion = null, + ) { + } +} diff --git a/tests/Trait/RequiresMoneroVersionTrait.php b/tests/Trait/RequiresMoneroVersionTrait.php new file mode 100644 index 0000000..3528a99 --- /dev/null +++ b/tests/Trait/RequiresMoneroVersionTrait.php @@ -0,0 +1,70 @@ +name()); + + // Check method-level attribute first, then class-level + $attributes = $reflection->getAttributes(RequiresMoneroVersion::class); + + if (empty($attributes)) { + $classReflection = $reflection->getDeclaringClass(); + $attributes = $classReflection->getAttributes(RequiresMoneroVersion::class); + } + + if (empty($attributes)) { + return; + } + + $requirement = $attributes[0]->newInstance(); + $currentVersion = $this->getDaemonVersion(); + $currentVersion = preg_replace('/[^0-9.]/', '', $currentVersion); + + if (version_compare($currentVersion, $requirement->minVersion, '<')) { + $this->markTestSkipped(sprintf( + 'Test requires Monero >= %s (current: %s)', + $requirement->minVersion, + $currentVersion + )); + } + + if ($requirement->maxVersion !== null) { + if (version_compare($currentVersion, $requirement->maxVersion, '>')) { + $this->markTestSkipped(sprintf( + 'Test requires Monero <= %s (current: %s)', + $requirement->maxVersion, + $currentVersion + )); + } + } + } + + private function getDaemonVersion(): string + { + if (self::$cachedDaemonVersion === null) { + self::$cachedDaemonVersion = static::getDaemonRpcClient()->getInfo()->version; + } + + return self::$cachedDaemonVersion; + } +} diff --git a/tests/integration/DaemonTest.php b/tests/integration/DaemonTest.php index ed9457b..5673d8b 100644 --- a/tests/integration/DaemonTest.php +++ b/tests/integration/DaemonTest.php @@ -11,9 +11,13 @@ use RefRing\MoneroRpcPhp\Enum\ResponseStatus; use RefRing\MoneroRpcPhp\Exception\InvalidHostOrSubnetException; use RefRing\MoneroRpcPhp\Exception\NoIpOrHostSuppliedException; +use RefRing\MoneroRpcPhp\Tests\Attribute\RequiresMoneroVersion; +use RefRing\MoneroRpcPhp\Tests\Trait\RequiresMoneroVersionTrait; final class DaemonTest extends TestCase { + use RequiresMoneroVersionTrait; + private static DaemonRpcClient $rpcClient; public static function setUpBeforeClass(): void @@ -22,6 +26,16 @@ public static function setUpBeforeClass(): void self::$rpcClient = new DaemonRpcClient($httpClient, getenv('DAEMON_RPC_URL')); } + protected function setUp(): void + { + $this->checkMoneroVersionRequirements(); + } + + protected static function getDaemonRpcClient(): DaemonRpcClient + { + return self::$rpcClient; + } + public function testSetBansOk(): void { $node = new Node('127.0.0.1', null, true, 60); @@ -37,12 +51,12 @@ public function testSetBansInvalidHost(): void $result = self::$rpcClient->setBans([$node]); } - // @TODO This will fail on versions before v0.18.4.0, find a way to only run tests against certain versions - // public function testSetBansMissingIp(): void - // { - // $this->expectException(NoIpOrHostSuppliedException::class); - // - // $node = new Node(null, null, true, 60); - // $result = self::$rpcClient->setBans([$node]); - // } + #[RequiresMoneroVersion('0.18.4.0')] + public function testSetBansMissingIp(): void + { + $this->expectException(NoIpOrHostSuppliedException::class); + + $node = new Node(null, null, true, 60); + $result = self::$rpcClient->setBans([$node]); + } } diff --git a/tests/unit/RequiresMoneroVersionTest.php b/tests/unit/RequiresMoneroVersionTest.php new file mode 100644 index 0000000..bcd90ab --- /dev/null +++ b/tests/unit/RequiresMoneroVersionTest.php @@ -0,0 +1,35 @@ +assertSame('0.18.4.0', $attr->minVersion); + $this->assertNull($attr->maxVersion); + } + + public function testAttributeInstantiationWithMax(): void + { + $attr = new RequiresMoneroVersion('0.18.0.0', '0.19.0.0'); + $this->assertSame('0.18.0.0', $attr->minVersion); + $this->assertSame('0.19.0.0', $attr->maxVersion); + } + + public function testVersionCompareWorks(): void + { + // Verify PHP's version_compare works correctly with Monero version strings + $this->assertSame(-1, version_compare('0.18.3.0', '0.18.4.0')); + $this->assertSame(0, version_compare('0.18.4.0', '0.18.4.0')); + $this->assertSame(1, version_compare('0.18.5.0', '0.18.4.0')); + $this->assertSame(-1, version_compare('0.17.3.2', '0.18.4.0')); + $this->assertSame(1, version_compare('0.19.0.0', '0.18.4.0')); + } +}