<?php namespace Tests\Feature; use Illuminate\Database\Eloquent\Collection; use Illuminate\Foundation\Testing\DatabaseTransactions; use Illuminate\Support\Facades\Cache; use Tests\TestCase; use App\Models\{Address,Domain,Setup,System}; /** * Here we test mail routing. * * - COMMON to all routing nodes * + We have RCs defined - everything for a node in the Region goes to an RC, unless RC's node defined locally, or nodes assigned to ZC * ie: region_id is the same, find the NC/HUB/NODE address for the system_id that has been assigned 0/0 in the same region. * nodes assigned to ZC have region_id = 0. Nodes with hub_id = NULL and host_id=0 are RC nodes. * + We have NCs defined - everything under the Host goes to the NC, unless NC's nodes defined locally or nodes assigned to the RC * ie: node_id defines the NCs responsible. Nodes with hub_id = NULL are an NC node. * + We have HUBs defined - everything under the Hub goes to the HUB, unless HUB's nodes defined locally * ie: hub_id defines who the hub is. * + We have NODES defined - mail collected locally, including mail for it's point * * - Routing scenarios: * - We are ZC for a domain * + See COMMON * + Everything else is collected locally * * - We are RC for a domain * + See COMMON * + Any nodes in our RC not defined with an NC is collected locally, including points * + Everything else is sent to the ZC (our uplink) * * - We are NC for a domain * + See COMMON * + Any nodes in our NC not defined with a HUB is collected locally, including points * + Everything else is sent to the RC or ZC (our uplink) * * - We are a Hub for a domain * + See COMMON * + Any nodes in our HUB is collected locally, including points * + Everything else is sent to the NC or RC (our uplink) * * - We are a Node in a domain * + See COMMON * + Everything else is sent to the HUB or Host or RC (our uplink) * * @see Address::uplink() * @see Address::downlinks() */ class RoutingTest extends TestCase { use DatabaseTransactions; private function zone(): Collection { //$this->seed(TestNodeHierarchy::class); $do = Domain::where('name','a')->singleOrFail(); $zo = $do->zones->where('zone_id',100)->pop(); return $zo->addresses; } private function session_zc(): void { $ao = Address::findFTN('101:0/0@a'); $ao->system->sessions()->attach([$ao->zone_id=>['sespass'=>'ABCD']]); } private function session_rc(): void { $ao = Address::findFTN('100:1/0@a'); $ao->system->sessions()->attach([$ao->zone_id=>['sespass'=>'ABCD']]); } private function session_nc(): void { $ao = Address::findFTN('100:10/0@a'); $ao->system->sessions()->attach([$ao->zone_id=>['sespass'=>'ABCD']]); } private function session_hub(): void { $ao = Address::findFTN('100:10/20@a'); $ao->system->sessions()->attach([$ao->zone_id=>['sespass'=>'ABCD']]); } // Make sure I'm configured correctly for the rest of the tests public function test_my_addresses() { $ftns = our_address(); $this->assertEquals(1,$ftns->count()); } // Get a list of active addresses in a Zone public function test_zc_addresses() { $nodes = $this->zone(); $this->assertEquals(936,$nodes->count()); } // Get a ZC with no session details, and make sure it has no parent nor children public function test_zc_no_session() { // Pick ZC without any session info - we have 0 children $ao = Address::findFTN('101:0/0@a'); $this->assertEquals($ao->role_id,Address::NODE_ZC); $this->assertCount(0,$ao->downstream()); $this->assertNull($ao->uplink()); } // If we have a ZC, make sure we are routing to all it's children public function test_zc_session_children() { $this->session_zc(); $ao = Address::findFTN('101:0/0@a'); $this->assertCount(935,$ao->downstream()); } // An RC's parent should be the ZC, when we have session details with parent public function test_zc_rc_node_parent() { $this->session_zc(); $ao = Address::findFTN('101:1/0@a'); $this->assertEquals($ao->role_id,Address::NODE_RC); $this->assertEquals('101:0/0.0@a',$ao->uplink()->ftn); } // Get a list of active addresses in a Region public function test_rc_session_children() { $this->session_rc(); $ao = Address::findFTN('100:1/0@a'); $this->assertCount(185,$ao->downstream()); } // An RCs node still collects mail from the RC public function test_rc_node_rc() { $this->session_rc(); // An RCs node should still be the RC $ao = Address::findFTN('100:1/100@a'); $this->assertEquals($ao->role_id,Address::NODE_NN); $this->assertEquals('100:1/0.0@a',$ao->uplink()->ftn); } // An NC collects mail for its children public function test_rc_nc_node_rc() { $this->session_rc(); // A NCs parent should still be the RC $ao = Address::findFTN('100:10/0@a'); $this->assertEquals($ao->role_id,Address::NODE_NC); $this->assertEquals('100:1/0.0@a',$ao->uplink()->ftn); } // A Hub still collects mail from NC public function test_rc_hub_node_nc() { $this->session_rc(); // A Hubs parent should still be the NC $ao = Address::findFTN('100:10/20.0@a'); $this->assertEquals($ao->role_id,Address::NODE_HC); $this->assertEquals('100:1/0.0@a',$ao->uplink()->ftn); } // A Hub's node still collects mail from Hub public function test_rc_hub_node_hub() { $this->session_rc(); // A Hubs node should still be the Hub $ao = Address::findFTN('100:10/22.0@a'); $this->assertEquals($ao->role_id,Address::NODE_NN); $this->assertEquals('100:1/0.0@a',$ao->uplink()->ftn); } // An RCs parent is us even if we have session details for another RC public function test_rc_parent() { $this->session_rc(); $ao = Address::findFTN('100:2/0@a'); $this->assertNull($ao->uplink()?->ftn); } // If we also have session details for an NC, then there are less RC nodes public function test_rc_nc_session_children() { $this->session_rc(); $this->session_nc(); $ao = Address::findFTN('100:1/0@a'); $this->assertCount(185-36,$ao->downstream()); } // If we also have session details for an Hub, then there are less RC nodes public function test_rc_hub_session_children() { $this->session_rc(); $ao = Address::findFTN('100:10/20@a'); $ao->system->sessions()->attach([$ao->zone_id=>['sespass'=>'ABCD']]); $ao = Address::findFTN('100:1/0@a'); $this->assertCount(185,$ao->downstream()); $ao = Address::findFTN('100:10/22@a'); $this->assertEquals('100:10/20.0@a',$ao->uplink()->ftn); } // If we also have session details for an Hub, then there are less RC nodes public function test_rc_hub_session_child() { $this->session_hub(); $ao = Address::findFTN('100:10/22@a'); $this->assertEquals('100:10/20.0@a',$ao->uplink()->ftn); } // When we have an RC with session details, we route to all its children public function test_nc_session_children() { $this->session_nc(); $ao = Address::findFTN('100:10/0@a'); $this->assertCount(35,$ao->downstream()); } public function test_complex_rc_nc_hc() { $this->session_rc(); $this->session_nc(); $this->session_hub(); $ao = Address::findFTN('100:1/100.0@a'); $this->assertCount(0,$ao->downstream()); $this->assertEquals('100:1/0.0@a',$ao->uplink()->ftn); // RC $ao = Address::findFTN('100:1/0.0@a'); $this->assertCount(186-1-30-6,$ao->downstream()); $ao = Address::findFTN('100:11/0.0@a'); $this->assertEquals('100:1/0.0@a',$ao->uplink()->ftn); // NC $ao = Address::findFTN('100:10/0.0@a'); $this->assertCount(36-1-6,$ao->downstream()); $ao = Address::findFTN('100:10/10.0@a'); $this->assertEquals('100:10/0.0@a',$ao->uplink()->ftn); // HC $ao = Address::findFTN('100:10/20.0@a'); $this->assertCount(6-1,$ao->downstream()); $ao = Address::findFTN('100:10/22.0@a'); $this->assertEquals('100:10/20.0@a',$ao->uplink()->ftn); } public function test_complex_rc_nc_hc_us() { Cache::forget('so'); $setup = Setup::findOrFail(config('app.id')); $ao = Address::findFTN('100:10/0.0@a'); $setup->system_id = $ao->system_id; $setup->save(); $this->assertEquals('100:10/0.0@a',our_address($ao)?->ftn); $this->session_rc(); //$this->session_nc(); $this->session_hub(); $ao = Address::findFTN('100:11/0.0'); $ao->system->sessions()->attach([$ao->zone_id=>['sespass'=>'ABCD']]); $ao = Address::findFTN('100:1/100.0@a'); $this->assertCount(0,$ao->downstream()); $this->assertEquals('100:1/0.0@a',$ao->uplink()?->ftn); // RC $ao = Address::findFTN('100:1/0.0@a'); $this->assertCount(186-36-36-1,$ao->downstream()); $ao = Address::findFTN('100:11/0.0@a'); $this->assertEquals('100:11/0.0@a',$ao->uplink()->ftn); // NC $ao = Address::findFTN('100:10/0.0@a'); $this->assertCount(36-6-1,$ao->downstream()); $ao = Address::findFTN('100:10/10.0@a'); $this->assertNull($ao->uplink()?->ftn); // HC $ao = Address::findFTN('100:10/20.0@a'); $this->assertCount(6-1,$ao->downstream()); $ao = Address::findFTN('100:10/22.0@a'); $this->assertEquals('100:10/20.0@a',$ao->uplink()->ftn); Cache::forget('so'); } // A points parent is the node, if we have traffic for a point and we have session details for the node public function test_point_session_node() { //$this->session_hub(); $so = new System; $so->name = 'Point System'; $so->sysop = 'Point Sysop'; $so->location = 'Melbourne, AU'; $so->active = TRUE; $so->save(); // Create a child $ao = Address::createFTN('100:10/21.2@a',$so); $ao = Address::findFTN('100:10/21.0@a'); $ao->system->sessions()->attach([$ao->zone_id=>['sespass'=>'ABCD']]); $ao = Address::findFTN('100:10/21.2@a'); $this->assertEquals('100:10/21.0@a',$ao->uplink()?->ftn); $ao = Address::findFTN('100:10/21@a'); $this->assertCount(1,$ao->downstream()); } }