123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224225226227228229230231232233234235236237238239240241242243244245246247248249250251252253254255256257258259260261262263264265266267268269270271272273274275276277278279280281282283284285286287288289290291292293294295296 |
- <?php
- namespace Tests\Unit\Utils;
- use App\Utils\NetworkDetection;
- use Exception;
- use Illuminate\Support\Facades\Http;
- use ReflectionClass;
- use Tests\TestCase;
- class NetworkDetectionTest extends TestCase
- {
- public static function providerDetectionServices(): array
- {
- return [
- 'toolsdaquan' => [[
- 'name' => 'toolsdaquan',
- 'responses' => [
- 'https://www.toolsdaquan.com/toolapi/public/ipchecking*' => '{"success":1,"msg":"检查成功","data":{"tcp":"success","icmp":"success","outside_tcp":"success","outside_icmp":"success"}}',
- ],
- 'expected' => [
- 'icmp' => 1,
- 'tcp' => 1,
- ],
- ]],
- 'vps234' => [[
- 'name' => 'vps234',
- 'responses' => [
- 'https://www.vps234.com/ipcheck/getdata/*' => '{"error":false,"data":{"success":true,"msg":"请求成功","data":{"innerICMP":true,"innerTCP":true,"outICMP":true,"outTCP":true}}}',
- ],
- 'expected' => [
- 'icmp' => 1,
- 'tcp' => 1,
- ],
- ]],
- 'idcoffer' => [[
- 'name' => 'idcoffer',
- 'responses' => [
- 'https://api.24kplus.com/ipcheck*' => '{"code":1,"message":"\u68C0\u67E5\u6210\u529F\uFF01","data":{"ping":true,"tcp":true,"ip":"220.181.7.203","countryClode":"CN"}}',
- 'https://api.idcoffer.com/ipcheck*' => '{"code":1,"message":"\u68C0\u67E5\u6210\u529F\uFF01","data":{"ping":true,"tcp":true,"ip":"220.181.7.203","countryClode":"HK"}}',
- ],
- 'expected' => [
- 'icmp' => 1,
- 'tcp' => 1,
- ],
- ]],
- 'ip112' => [[
- 'name' => 'ip112',
- 'responses' => [
- 'https://api.ycwxgzs.com/ipcheck/index.php' => '{"ip":"220.181.7.203","port":"443","tcp":"<span class=\"mdui-text-color-green\">\u7aef\u53e3\u53ef\u7528<\/span>","icmp":"<span class=\"mdui-text-color-green\">IP\u53ef\u7528<\/span>"}',
- 'https://api.52bwg.com/ipcheck/ipcheck.php' => '{"ip":"220.181.7.203","port":"443","tcp":"<span class=\"mdui-text-color-green\">\u7aef\u53e3\u53ef\u7528<\/span>","icmp":"<span class=\"mdui-text-color-green\">IP\u53ef\u7528<\/span>"}',
- ],
- 'expected' => [
- 'icmp' => 1,
- 'tcp' => 1,
- ],
- ]],
- 'upx8' => [[
- 'name' => 'upx8',
- 'responses' => [
- 'https://api.sm171.com/check-cn.php' => '{"ip":"220.181.7.203","port":"443","tcp":"\u6b63\u5e38","icmp":"\u6b63\u5e38"}',
- 'https://ip.upx8.com/api/check-us.php' => '{"ip":"220.181.7.203","port":"443","tcp":"\u6b63\u5e38","icmp":"\u6b63\u5e38"}',
- ],
- 'expected' => [
- 'icmp' => 1,
- 'tcp' => 1,
- ],
- ]],
- 'rss' => [[
- 'name' => 'rss',
- 'responses' => [
- 'https://ip.rss.ink/api/scan*' => '{"code":200,"data":"","msg":"Ok"}',
- 'https://tcp.mk/api/scan*' => '{"code":200,"data":"","msg":"Ok"}',
- ],
- 'expected' => [
- 'icmp' => 1,
- 'tcp' => 1,
- ],
- ]],
- 'vps1352' => [[
- 'name' => 'vps1352',
- 'responses' => [
- 'https://www.vps1352.com/check.php' => '{"ip":"220.181.7.203","port":"443","tcp":"\u5f00\u653e","icmp":"\u5f00\u653e"}',
- ],
- 'expected' => [
- 'icmp' => 1,
- 'tcp' => 1,
- ],
- ]],
- 'selfHost' => [[
- 'name' => 'selfHost',
- 'config' => ['services.probe.domestic' => 'test_domestic.com|test_token', 'services.probe.foreign' => 'test_foreign.com:8080'],
- 'responses' => [
- 'test_domestic.com*' => '[{"ip":"220.181.7.203","icmp":29.627562,"tcp":29.17411}]',
- 'test_foreign.com*' => '[{"ip":"220.181.7.203","icmp":29.627562,"tcp":29.17411}]',
- ],
- 'expected' => [
- 'icmp' => 1,
- 'tcp' => 1,
- ],
- ]],
- ];
- }
- /**
- * 测试所有检测服务
- *
- * @dataProvider providerDetectionServices
- */
- public function test_network_detection_services(array $case): void
- {
- // 准备响应
- if (! empty($case['config'])) { // 设置可能存在的假token参数,来激活 API 访问
- foreach ($case['config'] as $k => $v) {
- config([$k => $v]);
- }
- }
- $responses = array_map(static function ($response) {
- return Http::response($response);
- }, $case['responses']);
- // 添加通配符响应以防止意外请求
- $responses['*'] = Http::response(['error' => 'Not found'], 404);
- Http::fake($responses);
- $result = NetworkDetection::networkStatus($case['ip'] ?? '8.8.8.8', $case['port'] ?? 443, $case['name']);
- $this->assertIsArray($result, "Service {$case['name']} should return an array");
- foreach ($case['expected'] as $protocol => $status) {
- $this->assertEquals($status, $result[$protocol], "Service {$case['name']} protocol {$protocol} mismatch");
- }
- }
- /**
- * 测试被墙的情况.
- */
- public function test_network_status_detects_blocked_ips()
- {
- Http::fake([
- 'https://www.vps234.com/ipcheck/getdata/*' => Http::response([
- 'error' => false,
- 'data' => [
- 'success' => true,
- 'msg' => '请求成功',
- 'data' => [
- 'innerICMP' => false,
- 'innerTCP' => false,
- 'outICMP' => true,
- 'outTCP' => true,
- ],
- ],
- ]),
- '*' => Http::response(['error' => 'Not found'], 404),
- ]);
- $result = NetworkDetection::networkStatus('8.8.8.8', 443, 'vps234');
- $this->assertIsArray($result);
- $this->assertEquals(3, $result['icmp']); // 被墙
- $this->assertEquals(3, $result['tcp']); // 被墙
- }
- /**
- * 测试国外访问异常的情况.
- */
- public function test_network_status_detects_foreign_access_issues()
- {
- Http::fake([
- 'https://www.vps234.com/ipcheck/getdata/*' => Http::response([
- 'error' => false,
- 'data' => [
- 'success' => true,
- 'msg' => '请求成功',
- 'data' => [
- 'innerICMP' => true,
- 'innerTCP' => true,
- 'outICMP' => true,
- 'outTCP' => false,
- ],
- ],
- ]),
- '*' => Http::response(['error' => 'Not found'], 404),
- ]);
- $result = NetworkDetection::networkStatus('8.8.8.8', 443, 'vps234');
- $this->assertIsArray($result);
- $this->assertEquals(1, $result['icmp']); // 正常
- $this->assertEquals(2, $result['tcp']); // 国外访问异常
- }
- /**
- * 测试服务器宕机的情况.
- */
- public function test_network_status_detects_server_down()
- {
- Http::fake([
- 'https://www.vps234.com/ipcheck/getdata/*' => Http::response([
- 'error' => false,
- 'data' => [
- 'success' => true,
- 'data' => [
- 'innerICMP' => false,
- 'innerTCP' => false,
- 'outICMP' => false,
- 'outTCP' => false,
- ],
- ],
- ]),
- '*' => Http::response(['error' => 'Not found'], 404),
- ]);
- $result = NetworkDetection::networkStatus('8.8.8.8', 443, 'vps234');
- $this->assertIsArray($result);
- $this->assertEquals(4, $result['icmp']); // 服务器宕机
- $this->assertEquals(4, $result['tcp']); // 服务器宕机
- }
- /**
- * 测试当所有检测服务都失败时返回 null.
- */
- public function test_network_status_returns_null_when_all_services_fail()
- {
- Http::fake([
- '*' => Http::response(['error' => 'Service unavailable'], 500),
- ]);
- $result = NetworkDetection::networkStatus('8.8.8.8', 443);
- $this->assertNull($result);
- }
- /**
- * 测试真实可用的 IP.
- */
- public function test_real_ip_connectivity()
- {
- $successfulRequests = 0;
- $failedRequests = 0;
- $results = [];
- $ip = '220.181.7.203';
- $port = 443;
- foreach (['selfHost', 'vps234', 'idcoffer', 'ip112', 'upx8', 'rss', 'vps1352'] as $service) {
- try {
- $result = NetworkDetection::networkStatus($ip, $port, $service);
- if (is_array($result)) {
- $successfulRequests++;
- $results["{$ip}:{$port}-{$service}"] = $result;
- } else {
- $failedRequests++;
- $results["{$ip}:{$port}-{$service}"] = 'Failed to get result';
- }
- } catch (Exception $e) {
- $failedRequests++;
- $results["{$ip}:{$port}-{$service}"] = 'Exception: '.$e->getMessage();
- }
- }
- // 输出测试结果摘要
- echo "实际网络连通性测试结果:\n";
- echo "成功请求: {$successfulRequests}\n";
- echo "失败请求: {$failedRequests}\n";
- echo '总请求数: '.($successfulRequests + $failedRequests)."\n\n";
- // 输出详细结果
- foreach ($results as $testName => $result) {
- echo "[{$testName}] - ".json_encode($result, JSON_THROW_ON_ERROR | JSON_UNESCAPED_UNICODE)."\n";
- }
- $this->assertGreaterThan(0, $successfulRequests, '至少应有一个网络检测请求成功');
- }
- protected function setUp(): void
- {
- parent::setUp();
- // 清理 HTTP 假造与缓存
- Http::fake([]);
- // 重置 basicRequest
- $ref = new ReflectionClass(NetworkDetection::class);
- if ($ref->hasProperty('basicRequest')) {
- $prop = $ref->getProperty('basicRequest');
- $prop->setAccessible(true);
- $prop->setValue(null, null);
- }
- }
- }
|