1// Copyright © 2018 Enrico Stahn <enrico.stahn@gmail.com> 2// Licensed under the Apache License, Version 2.0 (the "License"); 3// you may not use this file except in compliance with the License. 4// You may obtain a copy of the License at 5// 6// http://www.apache.org/licenses/LICENSE-2.0 7// 8// Unless required by applicable law or agreed to in writing, software 9// distributed under the License is distributed on an "AS IS" BASIS, 10// WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. 11// See the License for the specific language governing permissions and 12// limitations under the License. 13 14package phpfpm 15 16import ( 17 "encoding/json" 18 "testing" 19 20 "github.com/stretchr/testify/assert" 21) 22 23func TestCountProcessState(t *testing.T) { 24 processes := []PoolProcess{ 25 {State: PoolProcessRequestIdle}, 26 {State: PoolProcessRequestRunning}, 27 {State: PoolProcessRequestReadingHeaders}, 28 {State: PoolProcessRequestInfo}, 29 {State: PoolProcessRequestFinishing}, 30 {State: PoolProcessRequestEnding}, 31 } 32 33 active, idle, total := CountProcessState(processes) 34 35 assert.Equal(t, int64(2), active, "active processes") 36 assert.Equal(t, int64(1), idle, "idle processes") 37 assert.Equal(t, int64(3), total, "total processes") 38} 39 40// https://github.com/hipages/php-fpm_exporter/issues/10 41func TestCannotUnmarshalNumberIssue10(t *testing.T) { 42 pool := Pool{} 43 content := []byte(`{ 44 "pool":"www", 45 "process manager":"dynamic", 46 "start time":1519474655, 47 "start since":302035, 48 "accepted conn":44144, 49 "listen queue":0, 50 "max listen queue":1, 51 "listen queue len":128, 52 "idle processes":1, 53 "active processes":1, 54 "total processes":2, 55 "max active processes":2, 56 "max children reached":0, 57 "slow requests":0, 58 "processes":[ 59 { 60 "pid":23, 61 "state":"Idle", 62 "start time":1519474655, 63 "start since":302035, 64 "requests":22071, 65 "request duration":295, 66 "request method":"GET", 67 "request uri":"/status?json&full", 68 "content length":0, 69 "user":"-", 70 "script":"-", 71 "last request cpu":0.00, 72 "last request memory":2097152 73 }, 74 { 75 "pid":24, 76 "state":"Running", 77 "start time":1519474655, 78 "start since":302035, 79 "requests":22073, 80 "request duration":18446744073709550774, 81 "request method":"GET", 82 "request uri":"/status?json&full", 83 "content length":0, 84 "user":"-", 85 "script":"-", 86 "last request cpu":0.00, 87 "last request memory":0 88 } 89 ] 90 }`) 91 92 err := json.Unmarshal(content, &pool) 93 94 assert.Nil(t, err, "successfully unmarshal on invalid 'request duration'") 95 assert.Equal(t, int(pool.Processes[0].RequestDuration), 295, "request duration set to 0 because it couldn't be deserialized") 96 assert.Equal(t, int(pool.Processes[1].RequestDuration), 0, "request duration set to 0 because it couldn't be deserialized") 97} 98 99// https://github.com/hipages/php-fpm_exporter/issues/24 100func TestInvalidCharacterIssue24(t *testing.T) { 101 // todo: Implement fcgi client dependency injection to allow testing of Pool.Update 102} 103 104func TestJsonResponseFixer(t *testing.T) { 105 pool := Pool{} 106 content := []byte(`{"pool":"www","process manager":"dynamic","start time":1528367006,"start since":15073840,"accepted conn":1577112,"listen queue":0,"max listen queue":0,"listen queue len":0,"idle processes":16,"active processes":1,"total processes":17,"max active processes":15,"max children reached":0,"slow requests":0, "processes":[{"pid":15873,"state":"Idle","start time":1543354120,"start since":86726,"requests":853,"request duration":5721,"request method":"GET","request uri":"/vbseo.php?ALTERNATE_TEMPLATES=|%20echo%20"Content-Type:%20text%2Fhtml"%3Becho%20""%20%3B%20id%00","content length":0,"user":"-","script":"/www/forum.example.com/vbseo.php","last request cpu":349.59,"last request memory":786432},{"pid":123,"state":"Idle","start time":1543354120,"start since":86726,"requests":853,"request duration":5721,"request method":"GET","request uri":"123/vbseo.php?ALTERNATE_TEMPLATES=|%20echo%20"Content-Type:%20text%2Fhtml"%3Becho%20""%20%3B%20id%00","content length":0,"user":"-","script":"/www/forum.example.com/vbseo.php","last request cpu":349.59,"last request memory":786432}]}`) 107 108 content = JSONResponseFixer(content) 109 110 err := json.Unmarshal(content, &pool) 111 112 assert.Nil(t, err, "successfully unmarshal on invalid 'request uri'") 113 assert.Equal(t, pool.Processes[0].RequestURI, `/vbseo.php?ALTERNATE_TEMPLATES=|%20echo%20"Content-Type:%20text%2Fhtml"%3Becho%20""%20%3B%20id%00`, "request uri couldn't be deserialized") 114 assert.Equal(t, pool.Processes[1].RequestURI, `123/vbseo.php?ALTERNATE_TEMPLATES=|%20echo%20"Content-Type:%20text%2Fhtml"%3Becho%20""%20%3B%20id%00`, "request uri couldn't be deserialized") 115} 116 117func TestParseURL(t *testing.T) { 118 var uris = []struct { 119 in string 120 out []string 121 err error 122 }{ 123 {"tcp://127.0.0.1:9000/status", []string{"tcp", "127.0.0.1:9000", "/status"}, nil}, 124 {"tcp://127.0.0.1", []string{"tcp", "127.0.0.1", ""}, nil}, 125 {"unix:///tmp/php.sock;/status", []string{"unix", "/tmp/php.sock", "/status"}, nil}, 126 {"unix:///tmp/php.sock", []string{"unix", "/tmp/php.sock", ""}, nil}, 127 } 128 129 for _, u := range uris { 130 scheme, address, path, err := parseURL(u.in) 131 assert.Equal(t, u.err, err) 132 assert.Equal(t, u.out, []string{scheme, address, path}) 133 } 134} 135