2013-11-22 04:10:53 +01:00
require 'spec_helper'
describe 'nginx::config' do
2014-12-08 02:47:29 +01:00
context 'with defaults' do
2014-07-18 04:28:38 +02:00
it { is_expected . to contain_file ( " /etc/nginx " ) . only_with (
2013-12-06 19:16:06 +01:00
:path = > " /etc/nginx " ,
2013-11-22 04:10:53 +01:00
:ensure = > 'directory' ,
:owner = > 'root' ,
:group = > 'root' ,
:mode = > '0644'
) }
2014-07-18 04:28:38 +02:00
it { is_expected . to contain_file ( " /etc/nginx/conf.d " ) . only_with (
2013-12-06 19:16:06 +01:00
:path = > '/etc/nginx/conf.d' ,
2013-11-22 04:10:53 +01:00
:ensure = > 'directory' ,
:owner = > 'root' ,
:group = > 'root' ,
:mode = > '0644'
) }
2014-07-18 04:28:38 +02:00
it { is_expected . to contain_file ( " /etc/nginx/conf.mail.d " ) . only_with (
2013-12-06 19:16:06 +01:00
:path = > '/etc/nginx/conf.mail.d' ,
2013-11-22 04:10:53 +01:00
:ensure = > 'directory' ,
:owner = > 'root' ,
:group = > 'root' ,
:mode = > '0644'
) }
2014-07-18 04:28:38 +02:00
it { is_expected . to contain_file ( " /etc/nginx/conf.d/vhost_autogen.conf " ) . with_ensure ( 'absent' ) }
it { is_expected . to contain_file ( " /etc/nginx/conf.mail.d/vhost_autogen.conf " ) . with_ensure ( 'absent' ) }
it { is_expected . to contain_file ( " /var/nginx " ) . with (
2013-11-22 04:10:53 +01:00
:ensure = > 'directory' ,
:owner = > 'root' ,
:group = > 'root' ,
:mode = > '0644'
) }
2014-07-18 04:28:38 +02:00
it { is_expected . to contain_file ( " /var/nginx/client_body_temp " ) . with (
2013-11-22 04:10:53 +01:00
:ensure = > 'directory' ,
:group = > 'root' ,
:mode = > '0644'
) }
2014-07-18 04:28:38 +02:00
it { is_expected . to contain_file ( " /var/nginx/proxy_temp " ) . with (
2013-11-22 04:10:53 +01:00
:ensure = > 'directory' ,
:group = > 'root' ,
:mode = > '0644'
) }
2014-07-18 04:28:38 +02:00
it { is_expected . to contain_file ( '/etc/nginx/sites-enabled/default' ) . with_ensure ( 'absent' ) }
it { is_expected . to contain_file ( " /etc/nginx/nginx.conf " ) . with (
2013-11-22 04:10:53 +01:00
:ensure = > 'file' ,
:owner = > 'root' ,
:group = > 'root' ,
:mode = > '0644'
) }
2014-07-18 04:28:38 +02:00
it { is_expected . to contain_file ( " /tmp/nginx.d " ) . with (
2013-12-02 19:58:23 +01:00
:ensure = > 'absent' ,
:purge = > true ,
2013-12-02 20:01:38 +01:00
:recurse = > true
2013-12-02 19:58:23 +01:00
) }
2014-07-18 04:28:38 +02:00
it { is_expected . to contain_file ( " /tmp/nginx.mail.d " ) . with (
2013-12-02 19:58:23 +01:00
:ensure = > 'absent' ,
:purge = > true ,
2013-12-02 20:01:38 +01:00
:recurse = > true
2013-12-02 19:58:23 +01:00
) }
2014-07-18 04:28:38 +02:00
it { is_expected . to contain_file ( " /var/nginx/client_body_temp " ) . with ( :owner = > 'nginx' ) }
it { is_expected . to contain_file ( " /var/nginx/proxy_temp " ) . with ( :owner = > 'nginx' ) }
it { is_expected . to contain_file ( " /etc/nginx/nginx.conf " ) . with_content %r{ ^user nginx; } }
2013-11-22 04:10:53 +01:00
2015-05-29 18:45:51 +02:00
it { is_expected . to contain_file ( " /var/log/nginx " ) . with (
:ensure = > 'directory' ,
:group = > 'root' ,
:mode = > '0644'
) }
2013-11-22 04:10:53 +01:00
describe " nginx.conf template content " do
[
2015-05-08 14:36:42 +02:00
{
:title = > 'should not set user' ,
:attr = > 'super_user' ,
:value = > false ,
:notmatch = > / user / ,
} ,
{
:title = > 'should set user' ,
:attr = > 'daemon_user' ,
:value = > 'test-user' ,
:match = > 'user test-user;' ,
} ,
2013-11-22 04:10:53 +01:00
{
:title = > 'should set worker_processes' ,
:attr = > 'worker_processes' ,
:value = > '4' ,
:match = > 'worker_processes 4;' ,
} ,
2015-04-02 05:34:31 +02:00
{
:title = > 'should set worker_processes' ,
:attr = > 'worker_processes' ,
:value = > 'auto' ,
:match = > 'worker_processes auto;' ,
} ,
2014-03-12 18:41:03 +01:00
{
:title = > 'should set worker_rlimit_nofile' ,
:attr = > 'worker_rlimit_nofile' ,
:value = > '10000' ,
:match = > 'worker_rlimit_nofile 10000;' ,
} ,
2013-11-22 04:10:53 +01:00
{
:title = > 'should set error_log' ,
:attr = > 'nginx_error_log' ,
:value = > '/path/to/error.log' ,
2015-11-01 14:14:08 +01:00
:match = > 'error_log /path/to/error.log error;' ,
} ,
{
:title = > 'should set error_log severity level' ,
:attr = > 'nginx_error_log_severity' ,
:value = > 'warn' ,
:match = > 'error_log /var/log/nginx/error.log warn;' ,
2013-11-22 04:10:53 +01:00
} ,
2015-05-08 14:36:42 +02:00
{
:title = > 'should set pid' ,
:attr = > 'pid' ,
:value = > '/path/to/pid' ,
:match = > 'pid /path/to/pid;' ,
} ,
{
:title = > 'should not set pid' ,
:attr = > 'pid' ,
:value = > false ,
:notmatch = > / pid / ,
} ,
2016-01-26 04:50:19 +01:00
{
:title = > 'should set accept_mutex on' ,
:attr = > 'accept_mutex' ,
:value = > 'on' ,
:match = > ' accept_mutex on;' ,
} ,
{
:title = > 'should set accept_mutex off' ,
:attr = > 'accept_mutex' ,
:value = > 'off' ,
:match = > ' accept_mutex off;' ,
} ,
{
:title = > 'should set accept_mutex_delay' ,
:attr = > 'accept_mutex_delay' ,
:value = > '500s' ,
:match = > ' accept_mutex_delay 500s;' ,
} ,
2013-11-22 04:10:53 +01:00
{
:title = > 'should set worker_connections' ,
:attr = > 'worker_connections' ,
:value = > '100' ,
:match = > ' worker_connections 100;' ,
} ,
2014-08-02 09:04:43 +02:00
{
:title = > 'should set log formats' ,
:attr = > 'log_format' ,
:value = > {
'format1' = > 'FORMAT1' ,
'format2' = > 'FORMAT2' ,
} ,
:match = > [
' log_format format1 \'FORMAT1\';' ,
' log_format format2 \'FORMAT2\';' ,
] ,
} ,
2014-12-04 05:26:00 +01:00
{
:title = > 'should not set log formats' ,
:attr = > 'log_format' ,
:value = > { } ,
:notmatch = > / log_format / ,
} ,
2015-05-08 14:36:42 +02:00
{
:title = > 'should set multi_accept' ,
:attr = > 'multi_accept' ,
:value = > 'on' ,
:match = > / \ s*multi_accept \ s+on; / ,
} ,
{
:title = > 'should not set multi_accept' ,
:attr = > 'multi_accept' ,
:value = > 'off' ,
:notmatch = > / multi_accept / ,
} ,
{
:title = > 'should set events_use' ,
:attr = > 'events_use' ,
:value = > 'eventport' ,
:match = > / \ s*use \ s+eventport; / ,
} ,
{
:title = > 'should not set events_use' ,
:attr = > 'events_use' ,
:value = > false ,
:notmatch = > / use / ,
} ,
2013-11-22 04:10:53 +01:00
{
:title = > 'should set access_log' ,
:attr = > 'http_access_log' ,
:value = > '/path/to/access.log' ,
:match = > ' access_log /path/to/access.log;' ,
} ,
2015-05-08 14:36:42 +02:00
{
:title = > 'should set sendfile' ,
:attr = > 'sendfile' ,
:value = > 'on' ,
:match = > ' sendfile on;' ,
} ,
{
:title = > 'should not set sendfile' ,
:attr = > 'sendfile' ,
:value = > false ,
:notmatch = > / sendfile / ,
} ,
2013-11-22 04:10:53 +01:00
{
:title = > 'should set server_tokens' ,
:attr = > 'server_tokens' ,
:value = > 'on' ,
:match = > ' server_tokens on;' ,
} ,
2015-05-08 14:36:42 +02:00
{
:title = > 'should set types_hash_max_size' ,
:attr = > 'types_hash_max_size' ,
:value = > 10 ,
:match = > ' types_hash_max_size 10;' ,
} ,
{
:title = > 'should set types_hash_bucket_size' ,
:attr = > 'types_hash_bucket_size' ,
:value = > 10 ,
:match = > ' types_hash_bucket_size 10;' ,
} ,
{
:title = > 'should set server_names_hash_bucket_size' ,
:attr = > 'names_hash_bucket_size' ,
:value = > 10 ,
:match = > ' server_names_hash_bucket_size 10;' ,
} ,
{
:title = > 'should set server_names_hash_max_size' ,
:attr = > 'names_hash_max_size' ,
:value = > 10 ,
:match = > ' server_names_hash_max_size 10;' ,
} ,
{
:title = > 'should set keepalive_timeout' ,
:attr = > 'keepalive_timeout' ,
:value = > '123' ,
:match = > ' keepalive_timeout 123;' ,
} ,
{
:title = > 'should set tcp_nodelay' ,
:attr = > 'http_tcp_nodelay' ,
:value = > 'on' ,
:match = > ' tcp_nodelay on;' ,
} ,
{
:title = > 'should set tcp_nopush' ,
:attr = > 'http_tcp_nopush' ,
:value = > 'on' ,
:match = > ' tcp_nopush on;' ,
} ,
{
:title = > 'should set gzip' ,
:attr = > 'gzip' ,
:value = > 'on' ,
2015-07-11 22:28:43 +02:00
:match = > ' gzip on;' ,
2015-05-08 14:36:42 +02:00
} ,
{
:title = > 'should not set gzip' ,
:attr = > 'gzip' ,
:value = > 'off' ,
:notmatch = > / gzip / ,
} ,
2015-07-11 22:28:43 +02:00
{
:title = > 'should set gzip_buffers' ,
:attr = > 'gzip_buffers' ,
:value = > '32 4k' ,
:match = > ' gzip_buffers 32 4k;' ,
} ,
{
:title = > 'should set gzip_comp_level' ,
:attr = > 'gzip_comp_level' ,
:value = > 5 ,
:match = > ' gzip_comp_level 5;' ,
} ,
{
:title = > 'should set gzip_disable' ,
:attr = > 'gzip_disable' ,
:value = > 'MSIE [1-6]\.(?!.*SV1)' ,
:match = > ' gzip_disable MSIE [1-6]\.(?!.*SV1);' ,
} ,
{
:title = > 'should set gzip_min_length' ,
:attr = > 'gzip_min_length' ,
:value = > '10' ,
:match = > ' gzip_min_length 10;' ,
} ,
{
:title = > 'should set gzip_http_version' ,
:attr = > 'gzip_http_version' ,
:value = > '1.0' ,
:match = > ' gzip_http_version 1.0;' ,
} ,
{
:title = > 'should set gzip_proxied' ,
:attr = > 'gzip_proxied' ,
:value = > 'any' ,
:match = > ' gzip_proxied any;' ,
} ,
{
:title = > 'should set gzip_types (array)' ,
:attr = > 'gzip_types' ,
:value = > [ 'text/plain' , 'text/html' ] ,
:match = > ' gzip_types text/plain text/html;' ,
} ,
{
:title = > 'should set gzip_types (string)' ,
:attr = > 'gzip_types' ,
:value = > [ 'text/plain' ] ,
:match = > ' gzip_types text/plain;' ,
} ,
{
:title = > 'should set gzip_vary' ,
:attr = > 'gzip_vary' ,
:value = > 'on' ,
:match = > ' gzip_vary on;' ,
} ,
2013-11-22 04:10:53 +01:00
{
:title = > 'should set proxy_cache_path' ,
:attr = > 'proxy_cache_path' ,
:value = > '/path/to/proxy.cache' ,
2014-09-12 19:42:51 +02:00
:match = > %r'\s+proxy_cache_path\s+/path/to/proxy.cache levels=1 keys_zone=d2:100m max_size=500m inactive=20m;' ,
2013-11-22 04:10:53 +01:00
} ,
{
:title = > 'should not set proxy_cache_path' ,
:attr = > 'proxy_cache_path' ,
:value = > false ,
2015-05-08 14:36:42 +02:00
:notmatch = > / proxy_cache_path / ,
} ,
{
:title = > 'should set fastcgi_cache_path' ,
:attr = > 'fastcgi_cache_path' ,
:value = > '/path/to/proxy.cache' ,
:match = > %r'\s*fastcgi_cache_path\s+/path/to/proxy.cache levels=1 keys_zone=d3:100m max_size=500m inactive=20m;' ,
} ,
{
:title = > 'should not set fastcgi_cache_path' ,
:attr = > 'fastcgi_cache_path' ,
:value = > false ,
:notmatch = > / fastcgi_cache_path / ,
} ,
{
:title = > 'should set fastcgi_cache_use_stale' ,
:attr = > 'fastcgi_cache_use_stale' ,
:value = > 'invalid_header' ,
:match = > ' fastcgi_cache_use_stale invalid_header;' ,
} ,
{
:title = > 'should not set fastcgi_cache_use_stale' ,
:attr = > 'fastcgi_cache_use_stale' ,
:value = > false ,
:notmatch = > / fastcgi_cache_use_stale / ,
2013-11-22 04:10:53 +01:00
} ,
{
2014-06-30 08:37:43 +02:00
:title = > 'should contain ordered appended directives from hash' ,
2013-11-22 04:10:53 +01:00
:attr = > 'http_cfg_append' ,
:value = > { 'test1' = > 'test value 1' , 'test2' = > 'test value 2' , 'allow' = > 'test value 3' } ,
:match = > [
' allow test value 3;' ,
' test1 test value 1;' ,
' test2 test value 2;' ,
] ,
} ,
2014-06-30 08:37:43 +02:00
{
:title = > 'should contain duplicate appended directives from list of hashes' ,
:attr = > 'http_cfg_append' ,
:value = > [ [ 'allow' , 'test value 1' ] , [ 'allow' , 'test value 2' ] ] ,
:match = > [
' allow test value 1;' ,
' allow test value 2;' ,
] ,
} ,
2014-12-11 16:41:47 +01:00
{
:title = > 'should contain duplicate appended directives from array values' ,
:attr = > 'http_cfg_append' ,
:value = > { 'test1' = > [ 'test value 1' , 'test value 2' , 'test value 3' ] } ,
:match = > [
' test1 test value 1;' ,
' test1 test value 2;' ,
] ,
} ,
2015-03-05 00:55:30 +01:00
{
:title = > 'should contain ordered appended directives from hash' ,
:attr = > 'nginx_cfg_prepend' ,
:value = > { 'test1' = > 'test value 1' , 'test2' = > 'test value 2' , 'allow' = > 'test value 3' } ,
:match = > [
'allow test value 3;' ,
'test1 test value 1;' ,
'test2 test value 2;' ,
] ,
} ,
{
:title = > 'should contain duplicate appended directives from list of hashes' ,
:attr = > 'nginx_cfg_prepend' ,
:value = > [ [ 'allow' , 'test value 1' ] , [ 'allow' , 'test value 2' ] ] ,
:match = > [
'allow test value 1;' ,
'allow test value 2;' ,
] ,
} ,
{
:title = > 'should contain duplicate appended directives from array values' ,
:attr = > 'nginx_cfg_prepend' ,
:value = > { 'test1' = > [ 'test value 1' , 'test value 2' , 'test value 3' ] } ,
:match = > [
'test1 test value 1;' ,
'test1 test value 2;' ,
'test1 test value 3;' ,
] ,
} ,
2014-06-24 01:28:21 +02:00
{
:title = > 'should set pid' ,
:attr = > 'pid' ,
:value = > '/path/to/pid' ,
:match = > 'pid /path/to/pid;' ,
} ,
{
:title = > 'should set tcp_nodelay' ,
:attr = > 'http_tcp_nodelay' ,
:value = > 'on' ,
:match = > ' tcp_nodelay on;' ,
} ,
{
:title = > 'should set tcp_nopush' ,
:attr = > 'http_tcp_nopush' ,
:value = > 'on' ,
:match = > ' tcp_nopush on;' ,
} ,
{
:title = > 'should set keepalive_timeout' ,
:attr = > 'keepalive_timeout' ,
:value = > '123' ,
:match = > ' keepalive_timeout 123;' ,
} ,
2015-05-08 14:36:42 +02:00
{
:title = > 'should set mail' ,
:attr = > 'mail' ,
:value = > true ,
:match = > 'mail {' ,
} ,
{
:title = > 'should not set mail' ,
:attr = > 'mail' ,
:value = > false ,
:notmatch = > / mail / ,
} ,
2013-11-22 04:10:53 +01:00
{
:title = > 'should set proxy_buffers' ,
:attr = > 'proxy_buffers' ,
:value = > '50 5k' ,
2015-06-15 14:44:16 +02:00
:match = > ' proxy_buffers 50 5k;' ,
2013-11-22 04:10:53 +01:00
} ,
{
:title = > 'should set proxy_buffer_size' ,
:attr = > 'proxy_buffer_size' ,
:value = > '2k' ,
2015-06-15 14:44:16 +02:00
:match = > ' proxy_buffer_size 2k;' ,
2013-11-22 04:10:53 +01:00
} ,
{
:title = > 'should set proxy_http_version' ,
:attr = > 'proxy_http_version' ,
:value = > '1.1' ,
2015-06-15 14:44:16 +02:00
:match = > ' proxy_http_version 1.1;' ,
2013-11-22 04:10:53 +01:00
} ,
2014-12-18 11:13:50 +01:00
{
:title = > 'should not set proxy_http_version' ,
:attr = > 'proxy_http_version' ,
:value = > nil ,
:notmatch = > 'proxy_http_version' ,
} ,
2013-11-22 04:10:53 +01:00
{
:title = > 'should contain ordered appended directives' ,
:attr = > 'proxy_set_header' ,
:value = > [ 'header1' , 'header2' ] ,
:match = > [
2015-06-15 14:44:16 +02:00
' proxy_set_header header1;' ,
' proxy_set_header header2;' ,
2013-11-22 04:10:53 +01:00
] ,
} ,
2014-06-23 23:32:22 +02:00
{
:title = > 'should set client_body_temp_path' ,
:attr = > 'client_body_temp_path' ,
:value = > '/path/to/body_temp' ,
2015-06-15 14:44:16 +02:00
:match = > ' client_body_temp_path /path/to/body_temp;' ,
2014-06-23 23:32:22 +02:00
} ,
{
:title = > 'should set proxy_temp_path' ,
:attr = > 'proxy_temp_path' ,
:value = > '/path/to/proxy_temp' ,
2015-06-15 14:44:16 +02:00
:match = > ' proxy_temp_path /path/to/proxy_temp;' ,
2014-06-23 23:32:22 +02:00
} ,
2013-11-22 04:10:53 +01:00
] . each do | param |
context " when #{ param [ :attr ] } is #{ param [ :value ] } " do
let :params do { param [ :attr ] . to_sym = > param [ :value ] } end
2015-06-15 14:44:16 +02:00
it { is_expected . to contain_file ( " /etc/nginx/nginx.conf " ) . with_mode ( '0644' ) }
2013-11-22 04:10:53 +01:00
it param [ :title ] do
2014-09-12 19:42:51 +02:00
matches = Array ( param [ :match ] )
if matches . all? { | m | m . is_a? Regexp }
2015-06-15 14:44:16 +02:00
matches . each { | item | is_expected . to contain_file ( '/etc/nginx/nginx.conf' ) . with_content ( item ) }
2014-09-12 19:42:51 +02:00
else
2015-06-15 14:44:16 +02:00
lines = catalogue . resource ( 'file' , '/etc/nginx/nginx.conf' ) . send ( :parameters ) [ :content ] . split ( " \n " )
2014-09-12 19:42:51 +02:00
expect ( lines & Array ( param [ :match ] ) ) . to eq ( Array ( param [ :match ] ) )
end
2013-12-06 17:36:28 +01:00
Array ( param [ :notmatch ] ) . each do | item |
2015-06-15 14:44:16 +02:00
is_expected . to contain_file ( " /etc/nginx/nginx.conf " ) . without_content ( item )
2013-12-06 17:36:28 +01:00
end
2013-11-22 04:10:53 +01:00
end
end
end
end
2015-05-08 14:36:42 +02:00
context " when conf_dir is /path/to/nginx " do
let ( :params ) { { :conf_dir = > '/path/to/nginx' } }
it { is_expected . to contain_file ( '/path/to/nginx/nginx.conf' ) . with_content ( %r{ include /path/to/nginx/mime \ .types; } ) }
it { is_expected . to contain_file ( '/path/to/nginx/nginx.conf' ) . with_content ( %r{ include /path/to/nginx/conf \ .d/ \ * \ .conf; } ) }
it { is_expected . to contain_file ( '/path/to/nginx/nginx.conf' ) . with_content ( %r{ include /path/to/nginx/sites-enabled/ \ *; } ) }
end
2013-11-22 04:10:53 +01:00
context " when confd_purge true " do
let ( :params ) { { :confd_purge = > true } }
2014-07-18 04:28:38 +02:00
it { is_expected . to contain_file ( '/etc/nginx/conf.d' ) . with (
2013-11-22 04:10:53 +01:00
:purge = > true ,
:recurse = > true
) }
end
context " when confd_purge false " do
let ( :params ) { { :confd_purge = > false } }
2014-07-18 04:28:38 +02:00
it { is_expected . to contain_file ( '/etc/nginx/conf.d' ) . without ( [
2013-11-22 04:10:53 +01:00
'ignore' ,
'purge' ,
'recurse'
] ) }
end
2014-03-07 20:39:40 +01:00
context " when vhost_purge true " do
let ( :params ) { { :vhost_purge = > true } }
2014-07-18 04:28:38 +02:00
it { is_expected . to contain_file ( '/etc/nginx/sites-available' ) . with (
2014-03-07 20:39:40 +01:00
:purge = > true ,
:recurse = > true
) }
2014-07-18 04:28:38 +02:00
it { is_expected . to contain_file ( '/etc/nginx/sites-enabled' ) . with (
2014-03-07 20:39:40 +01:00
:purge = > true ,
:recurse = > true
) }
end
context " when vhost_purge false " do
let ( :params ) { { :vhost_purge = > false } }
2014-07-18 04:28:38 +02:00
it { is_expected . to contain_file ( '/etc/nginx/sites-available' ) . without ( [
2014-03-07 20:39:40 +01:00
'ignore' ,
'purge' ,
'recurse'
] ) }
2014-07-18 04:28:38 +02:00
it { is_expected . to contain_file ( '/etc/nginx/sites-enabled' ) . without ( [
2014-03-07 20:39:40 +01:00
'ignore' ,
'purge' ,
'recurse'
] ) }
2015-05-29 18:45:51 +02:00
it { is_expected . to contain_file ( '/var/log/nginx' ) . without ( [
'ignore' ,
'purge' ,
'recurse'
] ) }
2014-03-07 20:39:40 +01:00
end
2014-12-08 02:47:29 +01:00
context " when daemon_user = www-data " do
let :params do
{
:daemon_user = > 'www-data' ,
}
end
it { is_expected . to contain_file ( " /var/nginx/client_body_temp " ) . with ( :owner = > 'www-data' ) }
it { is_expected . to contain_file ( " /var/nginx/proxy_temp " ) . with ( :owner = > 'www-data' ) }
it { is_expected . to contain_file ( " /etc/nginx/nginx.conf " ) . with_content %r{ ^user www-data; } }
end
2015-11-01 14:14:08 +01:00
context " when nginx_error_log_severity = invalid " do
let ( :params ) { { :nginx_error_log_severity = > 'invalid' } }
it { expect { is_expected . to contain_class ( 'nginx::config' ) } . to raise_error ( Puppet :: Error , / \ $nginx_error_log_severity must be debug, info, notice, warn, error, crit, alert or emerg / ) }
end
2013-11-22 04:10:53 +01:00
end
end