OverviewFilesCommitsIssuesDocsReleasesPeers

hyperident-gateway / test / manual-test.js

193 lines · javascript ref:
/**
 * Manual test script for GatewayIdentity with real hyperident setup
 *
 * Run: node test/manual-test.js
 */

import { GatewayIdentity } from '../lib/gateway-identity.js'
import { ServiceRegistry } from '../lib/service-registry.js'

console.log('🧪 Hyperident Gateway - Manual Test\n')
console.log('=' .repeat(60))

async function runTests() {
  try {
    // Test 1: Initialize GatewayIdentity
    console.log('\n📝 Test 1: Initialize GatewayIdentity')
    const identity = new GatewayIdentity({
      subnet: '10.22.0.0/16',
      staticMappings: {
        'git-daemon': '10.22.0.10',
        'fedicore': '10.22.0.5'
      }
    })
    console.log('✅ GatewayIdentity created')
    console.log(`   Subnet: ${identity.subnet}`)
    console.log(`   Network prefix: ${identity.networkPrefix}`)
    console.log(`   CIDR: /${identity.cidr}`)

    // Test 2: Load hyperident profiles
    console.log('\n📝 Test 2: Load hyperident profiles')
    try {
      const profiles = await identity.loadProfiles()
      console.log('✅ Profiles loaded from ~/.hyperident/')
      console.log(`   Found ${Object.keys(profiles).length} profiles:`)
      for (const [name, profile] of Object.entries(profiles)) {
        console.log(`   - ${name}: ${profile.description || '(no description)'}`)
      }
    } catch (error) {
      console.log(`⚠️  Could not load profiles: ${error.message}`)
      console.log('   Make sure hyperident is initialized:')
      console.log('   cd /home/fleeky/hyper-tests/hyperident && node index.js init')
      return
    }

    // Test 3: Topic derivation
    console.log('\n📝 Test 3: Derive topics from profiles')
    const profiles = await identity.loadProfiles()
    const profileNames = Object.keys(profiles).slice(0, 3) // Test first 3

    for (const profileName of profileNames) {
      const topic = await identity.deriveServiceTopic(profileName)
      const ip = identity.assignIP(topic)

      console.log(`\n   Profile: ${profileName}`)
      console.log(`   Topic:   ${topic.toString('hex').substring(0, 32)}...`)
      console.log(`   IP:      ${ip}`)
    }

    // Test 4: Determinism
    console.log('\n📝 Test 4: Verify deterministic IP assignment')
    const testProfile = profileNames[0]
    const topic1 = await identity.deriveServiceTopic(testProfile)
    const topic2 = await identity.deriveServiceTopic(testProfile)
    const ip1 = identity.assignIP(topic1)
    const ip2 = identity.assignIP(topic2)

    console.log(`   Profile: ${testProfile}`)
    console.log(`   Topic 1: ${topic1.toString('hex').substring(0, 16)}...`)
    console.log(`   Topic 2: ${topic2.toString('hex').substring(0, 16)}...`)
    console.log(`   IP 1:    ${ip1}`)
    console.log(`   IP 2:    ${ip2}`)

    if (topic1.toString('hex') === topic2.toString('hex') && ip1 === ip2) {
      console.log('   ✅ Deterministic: Same profile → same topic → same IP')
    } else {
      console.log('   ❌ NOT deterministic!')
    }

    // Test 5: Service registration
    console.log('\n📝 Test 5: Register services')

    // Only register if profiles exist
    if (profiles['git-daemon']) {
      const gitService = await identity.registerService({
        name: 'git-daemon',
        profile: 'git-daemon',
        port: 9418,
        transport: 'tcp'
      })
      console.log('\n   ✅ git-daemon registered')
      console.log(`      IP: ${gitService.ip}:${gitService.port}`)
      console.log(`      Topic: ${gitService.topic.substring(0, 16)}...`)
    } else {
      console.log('\n   ⚠️  Skipping git-daemon (profile not found)')
      console.log('      Create with: hyperident create-profile git-daemon')
    }

    if (profiles['fedicore']) {
      const fedicoreService = await identity.registerService({
        name: 'fedicore',
        profile: 'fedicore',
        port: 3000,
        transport: 'tcp'
      })
      console.log('\n   ✅ fedicore registered')
      console.log(`      IP: ${fedicoreService.ip}:${fedicoreService.port}`)
      console.log(`      Topic: ${fedicoreService.topic.substring(0, 16)}...`)
    } else {
      console.log('\n   ⚠️  Skipping fedicore (profile not found)')
      console.log('      Create with: hyperident create-profile fedicore')
    }

    // Test 6: Service lookup
    console.log('\n📝 Test 6: Service lookup')
    const services = identity.listServices()
    console.log(`   Registered services: ${services.length}`)

    for (const service of services) {
      const found = identity.lookup(service.ip)
      console.log(`   - ${service.name}: ${service.ip} → ${found ? '✅ Found' : '❌ Not found'}`)
    }

    // Test 7: ServiceRegistry
    console.log('\n📝 Test 7: ServiceRegistry')
    const registry = new ServiceRegistry(identity)
    const stats = registry.getStats()

    console.log(`   Total services: ${stats.total}`)
    console.log(`   Online: ${stats.online}`)
    console.log(`   Offline: ${stats.offline}`)
    console.log(`   Total connections: ${stats.totalConnections}`)

    // Test 8: Export mappings
    console.log('\n📝 Test 8: Export service mappings')
    const mappings = identity.exportMappings()
    console.log('   Service → IP mappings:')
    console.log(JSON.stringify(mappings, null, 2))

    // Test 9: Static IP mapping
    console.log('\n📝 Test 9: Verify static IP mappings')
    if (services.find(s => s.name === 'git-daemon')) {
      const gitService = services.find(s => s.name === 'git-daemon')
      if (gitService.ip === '10.22.0.10') {
        console.log('   ✅ git-daemon uses static IP: 10.22.0.10')
      } else {
        console.log(`   ⚠️  git-daemon IP: ${gitService.ip} (expected: 10.22.0.10)`)
      }
    }

    if (services.find(s => s.name === 'fedicore')) {
      const fedicoreService = services.find(s => s.name === 'fedicore')
      if (fedicoreService.ip === '10.22.0.5') {
        console.log('   ✅ fedicore uses static IP: 10.22.0.5')
      } else {
        console.log(`   ⚠️  fedicore IP: ${fedicoreService.ip} (expected: 10.22.0.5)`)
      }
    }

    // Test 10: Collision detection
    console.log('\n📝 Test 10: Collision detection')
    try {
      // Try to register same profile again (will cause collision)
      if (profiles['git-daemon']) {
        await identity.registerService({
          name: 'git-daemon-duplicate',
          profile: 'git-daemon', // Same profile = same topic = same IP
          port: 9999
        })
        console.log('   ❌ Should have detected collision!')
      }
    } catch (error) {
      console.log(`   ✅ Collision detected: ${error.message}`)
    }

    // Summary
    console.log('\n' + '='.repeat(60))
    console.log('📊 Test Summary')
    console.log('='.repeat(60))
    console.log('✅ All core features validated')
    console.log('\nNext steps:')
    console.log('- Implement UTUNManager for virtual network interface')
    console.log('- Implement HyperswarmRouter for P2P connections')
    console.log('- Test end-to-end packet routing')

  } catch (error) {
    console.error('\n❌ Test failed:', error.message)
    console.error(error.stack)
    process.exit(1)
  }
}

runTests()