File: ProcessMetricsCollectorTest.cpp

package info (click to toggle)
ruby-passenger 3.0.13debian-1%2Bdeb7u2
  • links: PTS, VCS
  • area: main
  • in suites: wheezy
  • size: 15,920 kB
  • sloc: cpp: 99,104; ruby: 18,098; ansic: 9,846; sh: 8,632; python: 141; makefile: 30
file content (121 lines) | stat: -rw-r--r-- 3,427 bytes parent folder | download | duplicates (2)
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
121
#include <sys/wait.h>
#include <signal.h>
#include <unistd.h>
#include <cstdio>
#include <cerrno>
#include "TestSupport.h"
#include "Utils/StrIntUtils.h"
#include "Utils/ProcessMetricsCollector.h"

using namespace Passenger;

namespace tut {
	struct ProcessMetricsCollectorTest {
		ProcessMetricsCollector collector;
		pid_t child;
		
		ProcessMetricsCollectorTest() {
			child = -1;
		}
		
		~ProcessMetricsCollectorTest() {
			if (child != -1) {
				kill(child, SIGKILL);
				waitpid(child, NULL, 0);
			}
		}
		
		pid_t spawnChild(int memory) {
			string memoryStr = toString(memory);
			pid_t pid = fork();
			if (pid == 0) {
				execlp("support/allocate_memory",
					"support/allocate_memory",
					memoryStr.c_str(),
					(char *) 0);
				
				int e = errno;
				fprintf(stderr, "Cannot execute support/allocate_memory: %s\n",
					strerror(e));
				fflush(stderr);
				_exit(1);
			} else {
				return pid;
			}
		}
	};
	
	DEFINE_TEST_GROUP(ProcessMetricsCollectorTest);
	
	TEST_METHOD(1) {
		// It collects the metrics for the given PIDs.
		collector.setPsOutput(
			"  PID  PPID  %CPU    RSS      VSZ  PGID COMMAND\n"
			"    1     0   0.0   1276  2456836     1 /sbin/launchd\n"
			"34678  1265  95.2   4128  2437812 34677 /bin/bash -li\n"
		);
		vector<pid_t> pids;
		pids.push_back(1);
		pids.push_back(34678);
		ProcessMetricMap result = collector.collect(pids);
		
		ensure_equals(result.size(), 2u);
		
		ensure_equals(result[1].pid, (pid_t) 1);
		ensure_equals(result[1].ppid, (pid_t) 0);
		ensure_equals(result[1].cpu, 0u);
		ensure_equals(result[1].rss, 1276u);
		ensure_equals(result[1].processGroupId, (pid_t) 1);
		ensure_equals(result[1].command, "/sbin/launchd");
		
		ensure_equals(result[34678].pid, (pid_t) 34678);
		ensure_equals(result[34678].ppid, (pid_t) 1265);
		ensure_equals(result[34678].cpu, 95u);
		ensure_equals(result[34678].rss, 4128u);
		ensure_equals(result[34678].processGroupId, (pid_t) 34677);
		ensure_equals(result[34678].command, "/bin/bash -li");
	}
	
	TEST_METHOD(2) {
		// It does not collect the metrics for PIDs that don't exist.
		collector.setPsOutput(
			"  PID  PPID  %CPU    RSS      VSZ  PGID COMMAND\n"
			"    1     0   0.0   1276  2456836     1 /sbin/launchd\n"
		);
		vector<pid_t> pids;
		pids.push_back(1);
		pids.push_back(34678);
		ProcessMetricMap result = collector.collect(pids);
		
		ensure_equals(result.size(), 1u);
		ensure(result.find(1) != result.end());
		ensure(result.find(34678) == result.end());
	}
	
	TEST_METHOD(3) {
		// Measuring real memory usage works.
		ssize_t pss, privateDirty, swap;
		child = spawnChild(50);
		usleep(500000);
		collector.measureRealMemory(child, pss, privateDirty, swap);
		#ifdef __APPLE__
			if (geteuid() == 0) {
				ensure(pss > 50000 && pss < 60000);
				ensure(privateDirty > 50000 && privateDirty < 60000);
				ensure_equals(swap, (ssize_t) -1);
			} else {
				ensure_equals(pss, (ssize_t) -1);
				ensure_equals(privateDirty, (ssize_t) -1);
				ensure_equals(swap, (ssize_t) -1);
			}
		#elif defined(__linux__)
			ensure("PSS is correct", (pss > 50000 && pss < 60000) || pss == -1);
			ensure("Private dirty is correct", privateDirty > 50000 && privateDirty < 60000);
			ensure("Swap is correct", swap < 10000);
		#else
			ensure((pss > 50000 && pss < 60000) || pss == -1);
			ensure((privateDirty > 50000 && privateDirty < 60000) || privateDirty == -1);
			ensure(swap < 10000 || swap == -1);
		#endif
	}
}