add load test
authorAlan <alan@roojs.com>
Tue, 17 Jan 2023 08:33:53 +0000 (16:33 +0800)
committerAlan <alan@roojs.com>
Tue, 17 Jan 2023 08:33:53 +0000 (16:33 +0800)
Import/Core_templatestr.php
Pman.Tab.AdminTranslations.bjs
Pman.Tab.AdminTranslations.js
Tools/LoadTest.php [new file with mode: 0644]

index fe0f851..47ace8d 100644 (file)
@@ -93,10 +93,39 @@ class Pman_Admin_Import_Core_templatestr extends Pman
         }
         return $ret;
     }        
-    
+    function updateTranslation($r)
+    {
+        // determine the type of file:
+        
+        if (empty($r['template']) || empty($r['module']) || empty($r['code'])) {
+            $this->jerr("missing template / module or code column");
+        }
+        if (isset($r['language'])) {
+            $this->updateTableTranslationRow($r);
+            return;
+        }
+        $ff = HTML_FlexyFramework::get();
+        if (!isset($ff->Pman_Admin['languages'])) {
+            $this->jerr("invalid language configuration");
+        }
+        
+        
+        foreach($ff->Pman_Admin['languages'] as $lang) {
+            if (!isset($r[strtolower($lang)])) {
+                //echo "SKIP $lang\n";
+                continue;
+            }
+            $rr = $r;
+            $rr['language'] = $lang;
+            $rr['translation'] = $r[strtolower($lang)];
+            $this->updateTranslationRow($rr);
+        }
+        
+        
+    }
     
     var $seq = 1;
-    function updateTranslation($r)
+    function updateTranslationRow($r)
     {
         //print_R($r); DB_DataObject::DebugLevel(1);
         $tr = DB_DataObject::Factory('core_templatestr');
@@ -114,7 +143,6 @@ class Pman_Admin_Import_Core_templatestr extends Pman
             $tt->txt = $r['translation'];
             $tt->updated = date('Y-m-d H:i:s');
             $tt->update($tr);
-             
             return 1;
         }
         return 0;
index 34ef06f..97441f0 100644 (file)
              "        csvTitles : 'Code,Module,Template,Original,Language,Translation',",
              "        limit : 9999,",
              "        sort: 'template_id_view_name,template_id_template,src_id_txt',",
-             "        dir: 'ASC'",
+             "        dir: 'ASC',",
+             "        active : 1",
              "    };",
              "    if (!sn ||  sn.id == 'transtree') {",
              "        Roo.MessageBox.alert(\"Error\", \"Select language, module or page\");",
index 1d5e235..b0d95d5 100644 (file)
@@ -295,7 +295,8 @@ Pman.Tab.AdminTranslations = new Roo.XComponent({
                    csvTitles : 'Code,Module,Template,Original,Language,Translation',
                    limit : 9999,
                    sort: 'template_id_view_name,template_id_template,src_id_txt',
-                   dir: 'ASC'
+                   dir: 'ASC',
+                   active : 1
                };
                if (!sn ||  sn.id == 'transtree') {
                    Roo.MessageBox.alert("Error", "Select language, module or page");
diff --git a/Tools/LoadTest.php b/Tools/LoadTest.php
new file mode 100644 (file)
index 0000000..9925841
--- /dev/null
@@ -0,0 +1,233 @@
+<?php
+
+
+require_once 'Pman/Core/Cli.php';
+class Pman_Admin_Tools_LoadTest extends Pman_Core_Cli
+{
+    
+    static $cli_desc = "Load testing for a domain";
+    
+    static $cli_opts = array(
+        
+        'per_second' => array(
+            'desc' => 'Request per second (default 1)',
+            'default' => '2',
+            'short' => 'P',
+            'max' => 1
+           
+        ),
+        
+        'timeout' => array(
+            'desc' => 'Timeout in seconds',
+             'default' => '5',
+            'short' => 'T' ,
+            'max' => 1
+        ),
+        'total' => array(
+            'desc' => 'Total tests (20)',
+             'default' => '20',
+            'short' => 't' ,
+            'max' => 1
+        ),
+        
+    );
+    // try and do some load testing..
+    var $total = 20; // total number of tests to run.
+    var $timeout = 5; // for each request.
+    var $per_second = 2; // how many per second.
+    var $host = 'www-new.regulationasia.com';
+    var $url = 'https://sg2-web.regulationasia.com/';
+    
+    var $cmd = ""; // filled in by initCmd
+    
+    var $started = 0;
+    var $done = array();
+    var $pool = array();
+    function get($r,$opts=array())    
+    {
+
+       // print_R($opts);exit;
+        foreach($opts as $k=>$v) {
+            $this->{$k} = $v;
+        }
+        $this->initCmd();
+
+        echo "Run:
+        
+Request Per Second: {$this->per_second}
+No. Requests : {$this->total}
+Timeout: {$this->timeout}
+URL: {$this->url}
+Host: {$this->host}
+CMD: {$this->cmd}
+
+";  
+        
+        
+        while (true) {
+             
+            
+            $ps = $this->poolsize();
+             
+            if ($this->started >= $this->total) {
+                if ($ps == 0) {
+                    break;
+                }
+                usleep((1.0/$this->per_second) * 1000000);
+                continue;
+            }
+            // run it..
+            $this->run();
+            $this->started++;
+            //echo "Sleep: " . ((1.0/$this->per_second) * 1000000) . "\n";
+            usleep((1.0/$this->per_second) * 1000000);
+            
+        }
+        $this->displayResults();
+        //print_R($this->done);
+        exit;
+    }
+    var $log = array();
+    var $keynames = array();
+    function initCmd()
+    {
+        require_once 'System.php';
+        $curl = System::which('curl');
+        $this->cmd = implode(" ", array(
+                $curl,
+                "--max-time " , $this->timeout , 
+                "-s -o /dev/null -k ",
+                "-H \"Host: {$this->host}\"",
+                "\"{$this->url}\"",
+                "-w \"%{http_code},%{size_download},%{time_connect},%{time_starttransfer},%{time_total}\n\""
+        ));
+        
+        $sn =  $_SERVER["SCRIPT_NAME"];
+        
+        $this->cwd = $sn[0] == '/' ? dirname($sn) : dirname(realpath(getcwd() . '/'. $sn));
+        
+        $this->keynames =array(
+            'success',
+            'size',
+            'connect',
+            'building',
+            'sent'
+        );
+        foreach($this->keynames as $k=>$v) {
+            $this->log[$v] = array();
+        }
+        
+        
+    }
+    
+    function run()
+    {
+       
+         
+         
+        $tn =  $this->tempName('stdout', true);
+        $descriptorspec = array(
+            0 => array("pipe", 'r'),  // stdin is a pipe that the child will read from
+            1 => array("file", $tn, 'w'),  // stdout is a pipe that the child will write to
+            2 => array("pipe", "w") // stderr is a file to write to
+        );
+        
+         
+        //$cmd = 'exec ' . $php . ' ' . $app . ' ' . $cmdOpts; //. ' &';
+        
+       
+        $pipe = array();
+         
+        //echo date("H:i:s"). ":Start: {$this->started} : {$this->cmd}\n";
+        
+        $p = proc_open($this->cmd, $descriptorspec, $pipes,  $this->cwd  );
+        $info =  proc_get_status($p);
+        
+         
+        $this->pool[] = array(
+                'proc' => $p,
+                'pid' => $info['pid'],
+                'out' => $tn,
+                'id' => $this->started,
+                //'cmd' => $cmd,
+                'pipes' => $pipes,
+                'started' => time()
+        );
+    }   
+       
+    
+    
+    function poolsize()
+    {
+        $pool = array();
+        clearstatcache();
+         
+        foreach($this->pool as $p) {
+             
+         
+            $info =  proc_get_status($p['proc']);
+            
+            // update if necessday.
+            if ($info['pid'] && $p['pid'] != $info['pid']) {
+                $p['pid'] = $info['pid'];
+            }
+            
+            
+            if ($info['running']) {
+            
+                $pool[] = $p;
+                continue;
+            }
+            // closed...
+            
+            
+            fclose($p['pipes'][0]);
+            fclose($p['pipes'][2]);
+            proc_close($p['proc']);
+            $res = trim(file_get_contents($p['out']));
+            
+            $p['data'] = explode(",", $res);
+            $this->done[] = $p;
+            foreach($p['data'] as $i=>$v) {
+                $this->log[$this->keynames[$i]][]  = $v;
+            }
+            $suc = $p['data'][0] == 200 ? 'Done' : 'Fail';
+            
+            echo date("H:i:s"). ":{$suc}: ". (1+$p['id']). "/{$this->total}: ";
+            $this->displayResults();
+            
+            
+            @unlink($p['out']);
+            
+        }
+        $this->pool = $pool;
+        return count($pool);
+        
+    }
+    
+    function displayResults()
+    {
+        $log = $this->log;
+        // we could slice log values to get recent.. // to show current trend.
+        
+        
+        $done = count($this->done);
+        echo
+            "Success Rate: ". number_format(100*(count(array_filter($log['success'], function($s) { return $s == 200; })) / $done), 0) . '%'.
+            "   Largest: " . number_format(max($log['size']),0) .'b'.  // these ignore failures.
+            "   Smallest: " . number_format(min($log['size']),0) .'b'.
+            "   Av.Connect: ".  number_format(array_sum($log['connect'])/$done, 2) .'s'.
+            "   Average Before Output Time: ", number_format(array_sum($log['building'])/$done, 2) .'s'.
+            "   Average Load Time: " .number_format(array_sum($log['sent'])/$done, 2) .'s' .
+            "   Load: {$this->per_second} req/s" .
+            "\n";
+            
+            
+            
+             
+        
+        
+        
+    }
+
+}
\ No newline at end of file