changeset 398:077ffeac825c

Tests: image filter tests.
author Sergey Kandaurov <pluknet@nginx.com>
date Wed, 14 May 2014 12:18:38 +0400
parents 847ea345becb
children c6ab68c41c8c
files image_filter.t
diffstat 1 files changed, 323 insertions(+), 0 deletions(-) [+]
line wrap: on
line diff
new file mode 100644
--- /dev/null
+++ b/image_filter.t
@@ -0,0 +1,323 @@
+#!/usr/bin/perl
+
+# (C) Sergey Kandaurov
+# (C) Nginx, Inc.
+
+# Tests for image filter module.
+
+###############################################################################
+
+use warnings;
+use strict;
+
+use Test::More;
+
+use Socket qw/CRLF/;
+
+BEGIN { use FindBin; chdir($FindBin::Bin); }
+
+use lib 'lib';
+use Test::Nginx;
+
+###############################################################################
+
+select STDERR; $| = 1;
+select STDOUT; $| = 1;
+
+eval { require GD; };
+plan(skip_all => 'GD not installed') if $@;
+
+my $t = Test::Nginx->new()->has(qw/http proxy map image/)->plan(39)
+	->write_file_expand('nginx.conf', <<'EOF');
+
+%%TEST_GLOBALS%%
+
+daemon off;
+
+events {
+}
+
+http {
+    %%TEST_GLOBALS_HTTP%%
+
+    map $arg_w $w {
+        "" '-';
+        default $arg_w;
+    }
+    map $arg_h $h {
+        "" '-';
+        default $arg_h;
+    }
+
+    server {
+        listen       127.0.0.1:8080;
+        server_name  localhost;
+
+        location /size {
+            image_filter size;
+            alias %%TESTDIR%%/;
+        }
+
+        location /test {
+            image_filter test;
+            alias %%TESTDIR%%/;
+
+            location /test/off {
+                image_filter off;
+                alias %%TESTDIR%%/;
+            }
+        }
+
+        location /resize {
+            image_filter resize 10 12;
+            alias %%TESTDIR%%/;
+        }
+        location /resize1 {
+            image_filter resize 10 -;
+            alias %%TESTDIR%%/;
+        }
+        location /resize2 {
+            image_filter resize - 12;
+            alias %%TESTDIR%%/;
+        }
+        location /resize_var {
+            image_filter resize $w $h;
+            alias %%TESTDIR%%/;
+        }
+
+        location /rotate {
+            image_filter rotate 90;
+            alias %%TESTDIR%%/;
+        }
+        location /rotate_var {
+            image_filter rotate $arg_r;
+            alias %%TESTDIR%%/;
+        }
+
+        location /crop {
+            image_filter crop 60 80;
+            alias %%TESTDIR%%/;
+        }
+        location /crop_var {
+            image_filter crop $arg_w $arg_h;
+            alias %%TESTDIR%%/;
+        }
+        location /crop_rotate {
+            image_filter crop $arg_w $arg_h;
+            image_filter rotate $arg_r;
+            alias %%TESTDIR%%/;
+        }
+        location /resize_rotate {
+            image_filter resize $w $h;
+            image_filter rotate $arg_r;
+            alias %%TESTDIR%%/;
+
+            location /resize_rotate/resize {
+                image_filter resize 10 12;
+                alias %%TESTDIR%%/;
+            }
+        }
+
+        location /interlaced {
+            image_filter resize 10 12;
+            image_filter_interlace on;
+            alias %%TESTDIR%%/;
+        }
+
+        location /nontransparent {
+            image_filter resize 10 12;
+            image_filter_transparency off;
+            alias %%TESTDIR%%/;
+        }
+
+        location /quality {
+            image_filter resize 10 12;
+            image_filter_jpeg_quality 50;
+            alias %%TESTDIR%%/;
+        }
+        location /quality_var {
+            image_filter resize 10 12;
+            image_filter_jpeg_quality $arg_q;
+            alias %%TESTDIR%%/;
+
+            location /quality_var/quality {
+                image_filter_jpeg_quality 60;
+                alias %%TESTDIR%%/;
+            }
+        }
+
+        location /buffer {
+            image_filter test;
+            image_filter_buffer 1k;
+            alias %%TESTDIR%%/;
+        }
+        location /proxy_buffer {
+            image_filter rotate 90;
+            image_filter_buffer 20;
+            proxy_pass http://127.0.0.1:8081/;
+            proxy_buffering off;
+            proxy_buffer_size 512;
+        }
+    }
+}
+
+EOF
+
+
+my $im = new GD::Image(100, 120);
+my $white = $im->colorAllocate(255, 255, 255);
+my $black = $im->colorAllocate(0, 0, 0);
+
+$im->transparent($white);
+$im->rectangle(0, 0, 99, 99, $black);
+
+$t->write_file('jpeg', $im->jpeg);
+$t->write_file('gif', $im->gif);
+$t->write_file('png', $im->png);
+$t->write_file('txt', 'SEE-THIS');
+
+$t->run_daemon(\&http_daemon, $t->testdir());
+$t->run()->waitforsocket('127.0.0.1:8081');
+
+###############################################################################
+
+like(http_head('/test/gif'), qr/200 OK/, 'test');
+like(http_head('/test/gif'), qr!Content-Type: image/gif!, 'test content-type');
+like(http_get('/test/txt'), qr/415 Unsupported/, 'test fail');
+like(http_get('/test/off/txt'), qr/SEE-THIS/, 'off');
+
+is(http_get_body('/size/txt'), '{}' . CRLF, 'size wrong type');
+like(http_head('/size/txt'), qr!Content-Type: application/json!,
+	'size content-type');
+like(http_get('/size/jpeg'), qr/"width": 100/, 'size width');
+like(http_get('/size/jpeg'), qr/"height": 120/, 'size height');
+like(http_get('/size/jpeg'), qr/"type": "jpeg"/, 'size jpeg');
+like(http_get('/size/gif'), qr/"type": "gif"/, 'size gif');
+like(http_get('/size/png'), qr/"type": "png"/, 'size png');
+
+is(gif_size('/resize/gif'), '10 12', 'resize');
+is(gif_size('/resize1/gif'), '10 12', 'resize 1');
+is(gif_size('/resize2/gif'), '10 12', 'resize 2');
+
+is(gif_size('/resize_var/gif?w=10&h=12'), '10 12', 'resize var');
+is(gif_size('/resize_var/gif?w=10'), '10 12', 'resize var 1');
+is(gif_size('/resize_var/gif?h=12'), '10 12', 'resize var 2');
+
+is(gif_size('/rotate/gif?r=90'), '120 100', 'rotate');
+is(gif_size('/rotate_var/gif?r=180'), '100 120', 'rotate var 1');
+is(gif_size('/rotate_var/gif?r=270'), '120 100', 'rotate var 2');
+
+$im = GD::Image->newFromGifData(http_get_body('/gif'));
+is($im->interlaced, 0, 'gif interlaced off');
+is($im->transparent, 0, 'gif transparent white');
+
+$im = GD::Image->newFromGifData(http_get_body('/interlaced/gif'));
+is($im->interlaced, 1, 'gif interlaced on');
+
+$im = GD::Image->newFromGifData(http_get_body('/nontransparent/gif'));
+is($im->transparent, -1, 'gif transparent loss');
+
+$im = GD::Image->newFromPngData(http_get_body('/png'));
+is($im->interlaced, 0, 'png interlaced off');
+is($im->transparent, 0, 'png transparent white');
+
+# this test produces libpng warning on STDERR:
+# "Interlace handling should be turned on when using png_read_image"
+
+SKIP: {
+skip 'can wedge nginx with SIGPIPE', 1 unless $ENV{TEST_NGINX_UNSAFE};
+
+$im = GD::Image->newFromPngData(http_get_body('/interlaced/png'));
+is($im->interlaced, 1, 'png interlaced on');
+
+}
+
+$im = GD::Image->newFromPngData(http_get_body('/nontransparent/png'));
+is($im->transparent, -1, 'png transparent loss');
+
+like(http_get('/resize/jpeg'), qr/quality = 75/, 'quality default');
+like(http_get('/quality/jpeg'), qr/quality = 50/, 'quality');
+like(http_get('/quality_var/jpeg?q=40'), qr/quality = 40/, 'quality var');
+like(http_get('/quality_var/quality/jpeg?q=40'), qr/quality = 60/,
+	'quality nested');
+
+is(gif_size('/crop/gif'), '60 80', 'crop');
+is(gif_size('/crop_var/gif?w=10&h=20'), '10 20', 'crop var');
+is(gif_size('/crop_rotate/gif?w=5&h=6&r=90'), '5 5', 'rotate before crop');
+is(gif_size('/resize_rotate/gif?w=5&h=6&r=90'), '6 5', 'rotate after resize');
+is(gif_size('/resize_rotate/resize/gif??w=5&h=6&r=90'), '10 12',
+	'resize rotate nested');
+
+like(http_get('/buffer/jpeg'), qr/415 Unsupported/, 'small buffer');
+isnt(http_get('/proxy_buffer/jpeg'), undef, 'small buffer proxy');
+
+###############################################################################
+
+sub gif_size {
+	join ' ', unpack("x6S2", http_get_body(@_));
+}
+
+sub http_get_body {
+	my ($uri) = @_;
+
+	return undef if !defined $uri;
+
+	my $text = http_get($uri);
+
+	if ($text !~ /(.*?)\x0d\x0a?\x0d\x0a?(.*)/ms) {
+		return undef;
+	}
+
+	return $2;
+}
+
+###############################################################################
+
+# serve static files without Content-Length
+
+sub http_daemon {
+	my ($root) = @_;
+
+	my $server = IO::Socket::INET->new(
+		Proto => 'tcp',
+		LocalHost => '127.0.0.1',
+		LocalPort => 8081,
+		Listen => 5,
+		Reuse => 1
+	)
+		or die "Can't create listening socket: $!\n";
+
+	local $SIG{PIPE} = 'IGNORE';
+
+	while (my $client = $server->accept()) {
+		$client->autoflush(1);
+
+		my $headers = '';
+		my $uri = '';
+
+		while (<$client>) {
+			$headers .= $_;
+			last if (/^\x0d?\x0a?$/);
+		}
+
+		next if $headers eq '';
+		$uri = $1 if $headers =~ /^\S+\s+([^ ]+)\s+HTTP/i;
+
+		open my $fh, '<', $root . $uri or next;
+		local $/;
+		my $data = <$fh>;
+		close $fh;
+
+		print $client <<EOF;
+HTTP/1.1 200 OK
+Connection: close
+
+$data
+EOF
+
+	} continue {
+		close $client;
+	}
+}
+
+###############################################################################