[pve-devel] [PATCH v2 common 1/6] extract PVE::Format from PVE::CLIFormatter for reuse

Stefan Reiter s.reiter at proxmox.com
Mon Feb 8 12:15:07 CET 2021


and add some tests

Signed-off-by: Stefan Reiter <s.reiter at proxmox.com>
---
 src/Makefile            |  1 +
 src/PVE/CLIFormatter.pm | 81 ++++++-----------------------------------
 src/PVE/Format.pm       | 77 +++++++++++++++++++++++++++++++++++++++
 test/format_test.pl     | 29 ++++++++++++++-
 4 files changed, 117 insertions(+), 71 deletions(-)
 create mode 100644 src/PVE/Format.pm

diff --git a/src/Makefile b/src/Makefile
index 098a648..13de6c6 100644
--- a/src/Makefile
+++ b/src/Makefile
@@ -16,6 +16,7 @@ LIB_SOURCES = \
 	CGroup.pm \
 	Daemon.pm \
 	Exception.pm \
+	Format.pm \
 	INotify.pm \
 	JSONSchema.pm \
 	LDAP.pm \
diff --git a/src/PVE/CLIFormatter.pm b/src/PVE/CLIFormatter.pm
index ccecfc3..c2f92d2 100644
--- a/src/PVE/CLIFormatter.pm
+++ b/src/PVE/CLIFormatter.pm
@@ -4,86 +4,27 @@ use strict;
 use warnings;
 
 use I18N::Langinfo;
-use POSIX qw(strftime);
 use YAML::XS; # supports Dumping JSON::PP::Boolean
 $YAML::XS::Boolean = "JSON::PP";
 
 use PVE::JSONSchema;
 use PVE::PTY;
+use PVE::Format;
 
 use JSON;
 use utf8;
 use Encode;
 
-sub render_timestamp {
-    my ($epoch) = @_;
-
-    # ISO 8601 date format
-    return strftime("%F %H:%M:%S", localtime($epoch));
-}
-
-PVE::JSONSchema::register_renderer('timestamp', \&render_timestamp);
-
-sub render_timestamp_gmt {
-    my ($epoch) = @_;
-
-    # ISO 8601 date format, standard Greenwich time zone
-    return strftime("%F %H:%M:%S", gmtime($epoch));
-}
-
-PVE::JSONSchema::register_renderer('timestamp_gmt', \&render_timestamp_gmt);
-
-sub render_duration {
-    my ($duration_in_seconds) = @_;
-
-    my $text = '';
-    my $rest = $duration_in_seconds;
-
-    my $step = sub {
-	my ($unit, $unitlength) = @_;
-
-	if ((my $v = int($rest/$unitlength)) > 0) {
-	    $text .= " " if length($text);
-	    $text .= "${v}${unit}";
-	    $rest -= $v * $unitlength;
-	}
-    };
-
-    $step->('w', 7*24*3600);
-    $step->('d', 24*3600);
-    $step->('h', 3600);
-    $step->('m', 60);
-    $step->('s', 1);
-
-    return $text;
-}
-
-PVE::JSONSchema::register_renderer('duration', \&render_duration);
-
-sub render_fraction_as_percentage {
-    my ($fraction) = @_;
-
-    return sprintf("%.2f%%", $fraction*100);
-}
-
-PVE::JSONSchema::register_renderer(
-    'fraction_as_percentage', \&render_fraction_as_percentage);
-
-sub render_bytes {
-    my ($value) = @_;
-
-    my @units = qw(B KiB MiB GiB TiB PiB);
-
-    my $max_unit = 0;
-    if ($value > 1023) {
-        $max_unit = int(log($value)/log(1024));
-        $value /= 1024**($max_unit);
-    }
-    my $unit = $units[$max_unit];
-    return sprintf "%.2f $unit", $value;
-}
-
-PVE::JSONSchema::register_renderer('bytes', \&render_bytes);
+PVE::JSONSchema::register_renderer('timestamp',
+    \&PVE::Format::render_timestamp);
+PVE::JSONSchema::register_renderer('timestamp_gmt',
+    \&PVE::Format::render_timestamp_gmt);
+PVE::JSONSchema::register_renderer('duration',
+    \&PVE::Format::render_duration);
+PVE::JSONSchema::register_renderer('fraction_as_percentage',
+    \&PVE::Format::render_fraction_as_percentage);
+PVE::JSONSchema::register_renderer('bytes',
+    \&PVE::Format::render_bytes);
 
 sub render_yaml {
     my ($value) = @_;
diff --git a/src/PVE/Format.pm b/src/PVE/Format.pm
new file mode 100644
index 0000000..7c3c062
--- /dev/null
+++ b/src/PVE/Format.pm
@@ -0,0 +1,77 @@
+package PVE::Format;
+
+use strict;
+use warnings;
+
+use POSIX qw(strftime);
+use PVE::JSONSchema;
+
+use base 'Exporter';
+our @EXPORT_OK = qw(
+render_timestamp
+render_timestamp_gmt
+render_duration
+render_fraction_as_percentage
+render_bytes
+);
+
+sub render_timestamp {
+    my ($epoch) = @_;
+
+    # ISO 8601 date format
+    return strftime("%F %H:%M:%S", localtime($epoch));
+}
+
+sub render_timestamp_gmt {
+    my ($epoch) = @_;
+
+    # ISO 8601 date format, standard Greenwich time zone
+    return strftime("%F %H:%M:%S", gmtime($epoch));
+}
+
+sub render_duration {
+    my ($duration_in_seconds) = @_;
+
+    my $text = '';
+    my $rest = $duration_in_seconds;
+
+    my $step = sub {
+	my ($unit, $unitlength) = @_;
+
+	if ((my $v = int($rest/$unitlength)) > 0) {
+	    $text .= " " if length($text);
+	    $text .= "${v}${unit}";
+	    $rest -= $v * $unitlength;
+	}
+    };
+
+    $step->('w', 7*24*3600);
+    $step->('d', 24*3600);
+    $step->('h', 3600);
+    $step->('m', 60);
+    $step->('s', 1);
+
+    return $text;
+}
+
+sub render_fraction_as_percentage {
+    my ($fraction) = @_;
+
+    return sprintf("%.2f%%", $fraction*100);
+}
+
+sub render_bytes {
+    my ($value, $precision) = @_;
+
+    my @units = qw(B KiB MiB GiB TiB PiB);
+
+    my $max_unit = 0;
+    if ($value > 1023) {
+        $max_unit = int(log($value)/log(1024));
+        $value /= 1024**($max_unit);
+    }
+    my $unit = $units[$max_unit];
+    return sprintf "%." . ($precision || 2) . "f $unit", $value;
+}
+
+1;
diff --git a/test/format_test.pl b/test/format_test.pl
index 3f225de..b6688ab 100755
--- a/test/format_test.pl
+++ b/test/format_test.pl
@@ -5,6 +5,7 @@ use warnings;
 
 use lib '../src';
 use PVE::JSONSchema;
+use PVE::CLIFormatter;
 
 use Test::More;
 use Test::MockModule;
@@ -24,4 +25,30 @@ foreach my $id (@$invalid_configids) {
     is(PVE::JSONSchema::pve_verify_configid($id, $noerr), undef, 'invalid configid');
 }
 
-done_testing();
\ No newline at end of file
+# test some string rendering
+my $render_data = [
+    ["timestamp", 0, undef, "1970-01-01 01:00:00"],
+    ["timestamp", 1612776831, undef, "2021-02-08 10:33:51"],
+    ["timestamp_gmt", 0, undef, "1970-01-01 00:00:00"],
+    ["timestamp_gmt", 1612776831, undef, "2021-02-08 09:33:51"],
+    ["duration", 0, undef, ""],
+    ["duration", 40, undef, "40s"],
+    ["duration", 60, undef, "1m"],
+    ["duration", 110, undef, "1m 50s"],
+    ["duration", 7*24*3829*2, undef, "2w 21h 22m 24s"],
+    ["fraction_as_percentage", 0.412, undef, "41.20%"],
+    ["bytes", 0, undef, "0.00 B"],
+    ["bytes", 1023, 4, "1023.0000 B"],
+    ["bytes", 1024, undef, "1.00 KiB"],
+    ["bytes", 1024*1024*123 + 1024*300, 1, "123.3 MiB"],
+    ["bytes", 1024*1024*1024*1024*4 + 1024*1024*2048*8, undef, "4.02 TiB"],
+];
+
+foreach my $data (@$render_data) {
+    my ($renderer_name, $p1, $p2, $expected) = @$data;
+    my $renderer = PVE::JSONSchema::get_renderer($renderer_name);
+    my $actual = $renderer->($p1, $p2);
+    is($actual, $expected, "string format '$renderer_name'");
+}
+
+done_testing();
-- 
2.20.1






More information about the pve-devel mailing list