~ubuntu-branches/ubuntu/oneiric/checkbox/oneiric-proposed

« back to all changes in this revision

Viewing changes to scripts/xorg_memory_test

  • Committer: Bazaar Package Importer
  • Author(s): Daniel Manrique, Marc Tardif, Chad A. Davis, Barry Warsaw
  • Date: 2011-07-01 11:37:27 UTC
  • Revision ID: james.westby@ubuntu.com-20110701113727-k4pekmtyr7v2i6le
Tags: 0.12.3
[ Marc Tardif ]
* Only reading CHECKBOX_* environment variables in config (LP: #802458)
* Imported scripts and jobs from Platform Services.

[Chad A. Davis]
* Switch to dh_python2 and debhelper7 (LP: #788514)

[Barry Warsaw]
* Fix checkbox_clean.run() to ignore missing executables, as is the case
  in a fresh checkout.

Show diffs side-by-side

added added

removed removed

Lines of Context:
 
1
#!/usr/bin/python
 
2
 
 
3
import commands
 
4
import subprocess
 
5
import os
 
6
import time
 
7
import sys
 
8
 
 
9
from optparse import OptionParser
 
10
from signal import SIGKILL
 
11
 
 
12
#globals
 
13
DEFAULT_MARGIN = 0.1
 
14
DEFAULT_PROCESSES = 100
 
15
DEFAULT_SAMPLES = 3
 
16
DEFAULT_SLEEP = 30
 
17
 
 
18
 
 
19
#process memory usage function
 
20
def mem_usage(process, samples=1):
 
21
    usage_sum = 0
 
22
 
 
23
    for n in xrange(1, samples + 1):
 
24
        pid = commands.getoutput("pidof %s" % process)
 
25
        output = commands.getoutput("pmap -d %s" % pid)
 
26
        if not output:
 
27
            raise Exception, "%s process not found" % process
 
28
 
 
29
        # mapped: 0K    writeable/private: 0K    shared: 0K
 
30
        lastline = output.splitlines()[-1]
 
31
        values = lastline.split()
 
32
        # use the mapped memory counter, remove trailing K.
 
33
        usage = int(values[1][:-1])
 
34
        usage_sum += usage
 
35
 
 
36
        if n < samples:
 
37
            time.sleep(3)
 
38
 
 
39
    return usage_sum / samples
 
40
 
 
41
def get_gem_objects():
 
42
    dri = commands.getoutput("xdriinfo")
 
43
    if not dri.startswith('Screen'):
 
44
        print >> sys.stderr, "xdriinfo fail : %s" % (dri)
 
45
        sys.exit(1)
 
46
    screen = dri.split()[1][:-1]
 
47
    path = os.path.join("/sys/kernel/debug/dri/", screen, "i915_gem_objects")
 
48
 
 
49
    # 2432 objects, 173256704 bytes
 
50
    try:
 
51
        file = open(path, 'r');
 
52
    except IOError:
 
53
        print >> sys.stderr, "File %s doesn't exist" % (path)
 
54
        sys.exit(1)
 
55
    objects_label, bytes_label = file.readline().split(", ")
 
56
    objects, label = objects_label.split(" ")
 
57
    return int(objects)
 
58
 
 
59
#compare pre-test and post-test video card mem values function
 
60
#there is a 10% margin
 
61
def compare_mem_results(orig, new, margin=0.1):
 
62
    return new < (orig + (orig * margin)) and new > (orig - (orig * margin))
 
63
 
 
64
def compare_gem_results(orig, new, margin=0.1):
 
65
    return new < (orig * ( 1 + margin )) and new > ( orig * ( 1 - margin ))
 
66
 
 
67
def start_processes(name, number=1):
 
68
    pids = []
 
69
    for n in xrange(number):
 
70
        pid = subprocess.Popen(name).pid
 
71
        pids.append(pid)
 
72
 
 
73
    return pids
 
74
 
 
75
def stop_processes(pids, signal=SIGKILL):
 
76
    for pid in pids:
 
77
        os.kill(pid, signal)
 
78
 
 
79
def main(args):
 
80
    #Parse options
 
81
    usage = "Usage: %prog [OPTIONS] PROGRAM"
 
82
    parser = OptionParser(usage=usage)
 
83
    parser.add_option("-m", "--margin",
 
84
        default=DEFAULT_MARGIN,
 
85
        type="float",
 
86
        help="Margin of error for memory usage (default %default)")
 
87
    parser.add_option("-p", "--processes",
 
88
        default=DEFAULT_PROCESSES,
 
89
        type="int",
 
90
        help="Number of processes to start and stop (default %default)")
 
91
    parser.add_option("--samples",
 
92
        default=DEFAULT_SAMPLES,
 
93
        type="int",
 
94
        help="Number of samples to get the memory usage (default %default)")
 
95
    parser.add_option("--sleep",
 
96
        default=DEFAULT_SLEEP,
 
97
        type="int",
 
98
        help="Seconds to sleep between starting and stopping processes (default %default)")
 
99
    (options, args) = parser.parse_args(args)
 
100
 
 
101
    #Parse args
 
102
    if not args:
 
103
        parser.error("Must specify a program to start")
 
104
    elif len(args) > 1:
 
105
        parser.error("Must only specify a single program to start")
 
106
 
 
107
    #Check current video card driver memory usage
 
108
    begin_mem_usage = mem_usage("X", options.samples)
 
109
 
 
110
    #Check current GEM object usage
 
111
    begin_gem_obj = get_gem_objects()
 
112
 
 
113
    #Open windows and let the system come upto speed
 
114
    pids = start_processes(args[0], options.processes)
 
115
    time.sleep(options.sleep)
 
116
 
 
117
    #Close windows
 
118
    stop_processes(pids)
 
119
    time.sleep(options.sleep)
 
120
 
 
121
    #Check video card driver's memory usage again to see if it returned to
 
122
    #value found previously (give system time to normalize)
 
123
    end_mem_usage = mem_usage("X", options.samples)
 
124
 
 
125
    #Check GEM object usage again, for state after running processes
 
126
    end_gem_obj = get_gem_objects()
 
127
 
 
128
    #compare new memory value to old memory value
 
129
    if not compare_mem_results(begin_mem_usage, end_mem_usage, options.margin):
 
130
        return "Xorg memory leak detected, before %d and after %d" \
 
131
            % (begin_mem_usage, end_mem_usage)
 
132
    if not compare_gem_results(begin_gem_obj, end_gem_obj, options.margin):
 
133
        return "DRI GEM objects leak detected, before %d and after %d" \
 
134
            % (begin_gem_obj, end_gem_obj)
 
135
 
 
136
    return 0
 
137
 
 
138
if __name__ == "__main__":
 
139
    sys.exit(main(sys.argv[1:]))