增加测试机制;完善DebugMysql日志逻辑;更新debug_log表字段格式;发布新版本

This commit is contained in:
2024-01-03 16:22:01 +08:00
parent 58bb8166c9
commit e6779f4921
14 changed files with 767 additions and 76 deletions

View File

@@ -0,0 +1,58 @@
<?php
namespace base\common\command;
use app\common\interface\test\CommandTestInterface;
use app\common\service\test\LogTestService;
use think\console\Command;
use think\console\Input;
use think\console\input\Option;
use think\console\Output;
class TestBase extends Command
{
protected $program = [
LogTestService::NAME => LogTestService::class,
];
protected function configure()
{
// 指令配置
$this->setName('test')
->addArgument('program', Option::VALUE_REQUIRED, '测试项目')
->setDescription('the admin:update command');
}
protected function execute(Input $input, Output $output)
{
$program = $input->getArgument('program');
if (empty($program)) {
$output->writeln('请输入测试项目');
return;
}
if (!isset($this->program[$program])) {
$output->writeln('测试项目不存在');
return;
}
$class = $this->program[$program];
$run = $class::RUN;
$instance = new $class();
$output->writeln('测试项目名称:' . $instance->getName());
$output->writeln('测试项目描述:' . $instance->getDesc());
if ($instance instanceof CommandTestInterface) {
$instance->setInput($input);
$instance->setOutput($output);
}
$instance->$run();
}
}

View File

@@ -12,12 +12,14 @@ use think\console\Output;
class VersionBase extends Command
{
public const VERSION = 'v2.0.85';
public const VERSION = 'v2.0.86';
public const LAYUI_VERSION = '2.8.17';
public const COMMENT = [
'优化搜索查询构造逻辑',
'增加测试机制',
'完善DebugMysql日志逻辑',
'更新debug_log表字段格式',
'发布新版本',
];

View File

@@ -0,0 +1,19 @@
<?php
namespace base\common\interface\test;
use think\console\Input;
use think\console\Output;
/**
* 测试类接口.
*
* 实现了该接口的类,会在执行命令时,自动执行该接口的方法,比如传入参数,输出结果等。
* 要注意的是并不代表该接口只能在命令行中使用也可以在其他地方使用在其他地方使用时传入不同“实现”的output和input。例如在控制器中使用传入的output会输出到Response。
*/
interface CommandTestInterfaceBase
{
public function setOutput(Output $output);
public function setInput(Input $input);
}

View File

@@ -0,0 +1,32 @@
<?php
namespace base\common\service;
use Exception;
class TestServiceBase
{
public const NAME = null;
public const DESC = null;
public const RUN = 'run';
public function getName()
{
if ($this::NAME === null) {
throw new Exception('name is not set');
}
return $this::NAME;
}
public function getDesc()
{
if ($this::DESC === null) {
throw new Exception('desc is not set');
}
return $this::DESC;
}
}

View File

@@ -0,0 +1,315 @@
<?php
namespace base\common\service\test;
use app\common\interface\test\CommandTestInterface;
use app\common\service\TestService;
use think\console\Input;
use think\console\Output;
use think\console\Table;
use think\facade\Log;
class LogTesServicetBase extends TestService implements CommandTestInterface
{
public const NAME = 'log';
public const DESC = '测试mysqllog驱动的兼容性、性能、边界情况';
public const RUN = 'run';
/**
* @var Output
*/
protected $output;
/**
* @var Input
*/
protected $input;
protected $summary = [];
protected $configContent = '';
public function run()
{
$this->getLogInfo();
$this->output->writeln(str_repeat('=', 50));
$this->testLogContent();
$this->output->writeln(str_repeat('=', 50));
$this->testIoTimes();
$this->output->writeln(str_repeat('=', 50));
$this->testIoSize();
$this->output->writeln(str_repeat('=', 50));
$this->testNetworkChange();
$this->output->writeln(str_repeat('=', 50));
$this->output->writeln($this->configContent);
$this->output->writeln('测试结果汇总');
$output_table = new Table();
$output_table->setHeader(['测试项', '测试描述', '测试结果']);
$output_table->setRows($this->summary);
$table_content = $output_table->render();
$this->output->writeln($table_content);
}
protected function getLogInfo()
{
$this->output->writeln('当前日志配置项');
$config = Log::getConfig();
$table = array_to_table($config);
$output_table = new Table();
$output_table->setHeader(['配置项', '配置值']);
$output_table->setRows($table);
$table_content = $output_table->render();
$this->configContent = $table_content;
$this->output->writeln($table_content);
$this->output->writeln('当前日志驱动:' . $config['default']);
}
public function testIoTimes()
{
$this->output->writeln('测试写入100条记录统计写入时间');
$start_time = microtime(true);
$total_times = 100;
for ($i = 0; $i < $total_times; $i++) {
$log_content = date('Y-m-d H:i:s');
Log::record($log_content, 'info');
$this->output->writeln("({$i}/{$total_times})写入日志:{$log_content}");
}
$end_time = microtime(true);
$time = $end_time - $start_time;
$this->output->writeln('测试完成');
$this->output->writeln("总写入时间:{$time}");
$this->summary[] = [
'title' => '写入次数测试',
'desc' => '测试写入100条记录统计写入时间',
'result' => "总写入时间:{$time}",
];
}
public function testIoSize()
{
$this->output->writeln('测试大内容写入,统计写入时间和写入大小');
$this->output->writeln('程序会写入100条记录间隔1秒日志内容为100KB的字符串');
$num = 0;
$total = 100;
$log_content = str_repeat('test', 100 * 1000);
$total_size = 0;
$total_time = 0;
while ($num < $total) {
$num++;
$start_time = microtime(true);
Log::record($log_content, 'info');
$end_time = microtime(true);
$time = $end_time - $start_time;
$total_time += $time;
$size = strlen($log_content);
$total_size += $size;
$size = format_bytes($size);
$this->output->writeln("({$num}/{$total})写入大小:{$size},写入时间:{$time}");
}
$this->output->writeln('测试完成');
$total_size = format_bytes($total_size);
$this->output->writeln("总写入大小:{$total_size},总写入时间:{$total_time}");
$this->summary[] = [
'title' => '写入大小测试',
'desc' => '测试大内容写入,统计写入时间和写入大小',
'result' => "总写入大小:{$total_size},总写入时间:{$total_time}",
];
}
public function testNetworkChange()
{
$this->output->writeln('测试网络切换');
$this->output->writeln('程序会写入30条记录间隔1秒日志内容为当前时间测试期间可以反复断开网络连接查看是否丢失或报错');
$num = 0;
$total = 30;
while ($num < $total) {
$num++;
$log_content = date('Y-m-d H:i:s');
Log::record($log_content, 'info');
$this->output->writeln("({$num}/{$total})写入日志:{$log_content}");
sleep(1);
}
$this->output->writeln('测试完成');
$this->summary[] = [
'title' => '网络切换测试',
'desc' => '测试网络切换',
'result' => '请查看是否有丢失',
];
}
public function testLogContent()
{
$this->output->writeln('测试日志内容兼容性');
$test_content_item = [];
// 生成测试内容包括简单英文字符串、中文字符串、大文本、数字、大数字、负数、负数大数字、数组、对象、资源、布尔值、null、空字符串、空数组、空对象、空资源、空布尔值
$test_content_item[] = [
'name' => '简单字符串',
'content' => 'test',
];
$test_content_item[] = [
'name' => '中文字符串',
'content' => '测试',
];
$test_content_item[] = [
'name' => '大文本',
'content' => str_repeat('test测试', 1000),
];
$test_content_item[] = [
'name' => '数字',
'content' => 1,
];
$test_content_item[] = [
'name' => '大数字',
'content' => 100000 * 100000,
];
$test_content_item[] = [
'name' => '负数',
'content' => -1,
];
$test_content_item[] = [
'name' => '负数大数字',
'content' => -100000 * 100000,
];
$test_content_item[] = [
'name' => '数组',
'content' => [
'test' => 'test',
'测试' => '测试',
],
];
$test_content_item[] = [
'name' => '对象',
'content' => new \stdClass(),
];
$test_content_item[] = [
'name' => '资源',
'content' => fopen(__FILE__, 'r'),
];
$test_content_item[] = [
'name' => '布尔值',
'content' => true,
];
$test_content_item[] = [
'name' => 'null',
'content' => null,
];
$test_content_item[] = [
'name' => '空字符串',
'content' => '',
];
$test_content_item[] = [
'name' => '空数组',
'content' => [],
];
$test_content_item[] = [
'name' => '空对象',
'content' => new \stdClass(),
];
$test_content_item[] = [
'name' => '空资源',
'content' => fopen('php://memory', 'r'),
];
$test_content_item[] = [
'name' => '空布尔值',
'content' => false,
];
$test_content_item[] = [
'name' => '异常',
'content' => new \Exception('test'),
];
$fail_count = 0;
foreach ($test_content_item as $key => $value) {
try {
$total_count = count($test_content_item);
$num = $key + 1;
Log::record($value['content'], 'info');
$this->output->writeln("({$num}/{$total_count})" . '测试内容:' . $value['name'] . ',测试结果:成功');
} catch (\Throwable $th) {
$this->output->writeln('测试内容失败:' . $value['name'] . ',测试结果:' . $th->getMessage());
if ($this->output->isDebug()) {
$this->output->error($th);
break;
}
$fail_count++;
}
}
$this->output->writeln('测试完成');
$this->summary[] = [
'title' => '日志内容兼容性测试',
'desc' => '测试日志内容兼容性',
'result' => "测试完成,失败{$fail_count}",
];
}
public function setOutput(Output $output)
{
$this->output = $output;
}
public function setInput(Input $input)
{
$this->input = $input;
}
}