1from webkit.basesteps import ShellCommand, SVN, Test, Compile, UploadCommand
2from buildbot.status.builder import SUCCESS, FAILURE, WARNINGS
3
4class CheckOutSource(SVN):
5    baseURL = "http://svn.webkit.org/repository/webkit/"
6    mode = "update"
7    def __init__(self, *args, **kwargs):
8        SVN.__init__(self, baseURL=self.baseURL, defaultBranch="trunk", mode=self.mode, *args, **kwargs)
9
10class SetConfiguration(ShellCommand):
11    command = ["perl", "./WebKitTools/Scripts/set-webkit-configuration"]
12
13    def __init__(self, *args, **kwargs):
14        configuration = kwargs.pop('configuration')
15        self.command = self.command + ['--' + configuration]
16        self.name = "set-configuration-%s" % (configuration,  )
17        self.description = ["set configuration %s" % (configuration, )]
18        self.descriptionDone = ["set configuration %s" % (configuration, )]
19        ShellCommand.__init__(self, *args, **kwargs)
20
21
22class LayoutTest(Test):
23    name = "layout-test"
24    description = ["layout-tests running"]
25    descriptionDone = ["layout-tests"]
26    command = ["perl", "./WebKitTools/Scripts/run-webkit-tests", "--no-launch-safari", "--no-new-test-results", "--no-sample-on-timeout", "--results-directory", "layout-test-results"]
27
28    def commandComplete(self, cmd):
29        Test.commandComplete(self, cmd)
30
31        logText = cmd.logs['stdio'].getText()
32        incorrectLayoutLines = [line for line in logText.splitlines() if line.find('had incorrect layout') >= 0 or (line.find('test case') >= 0 and (line.find(' crashed') >= 0 or line.find(' timed out') >= 0))]
33        self.incorrectLayoutLines = incorrectLayoutLines
34
35    def evaluateCommand(self, cmd):
36        if self.incorrectLayoutLines or cmd.rc != 0:
37            return FAILURE
38
39        return SUCCESS
40
41    def getText(self, cmd, results):
42        return self.getText2(cmd, results)
43
44    def getText2(self, cmd, results):
45        if results != SUCCESS and self.incorrectLayoutLines:
46            return self.incorrectLayoutLines
47
48        return [self.name]
49
50
51class JavaScriptCoreTest(Test):
52    name = "jscore-test"
53    description = ["jscore-tests running"]
54    descriptionDone = ["jscore-tests"]
55    command = ["perl", "./WebKitTools/Scripts/run-javascriptcore-tests"]
56    logfiles = {'results': 'JavaScriptCore/tests/mozilla/actual.html'}
57
58    def commandComplete(self, cmd):
59        Test.commandComplete(self, cmd)
60
61        logText = cmd.logs['stdio'].getText()
62        statusLines = [line for line in logText.splitlines() if line.find('regression') >= 0 and line.find(' found.') >= 0]
63        if statusLines and statusLines[0].split()[0] != '0':
64            self.regressionLine = statusLines[0]
65        else:
66            self.regressionLine = None
67
68    def evaluateCommand(self, cmd):
69        if self.regressionLine:
70            return FAILURE
71
72        if cmd.rc != 0:
73            return FAILURE
74
75        return SUCCESS
76
77    def getText(self, cmd, results):
78        return self.getText2(cmd, results)
79
80    def getText2(self, cmd, results):
81        if results != SUCCESS and self.regressionLine:
82            return [self.name, self.regressionLine]
83
84        return [self.name]
85
86class PixelLayoutTest(LayoutTest):
87    name = "pixel-layout-test"
88    description = ["pixel-layout-tests running"]
89    descriptionDone = ["pixel-layout-tests"]
90    command = LayoutTest.command + ["--pixel", "--tolerance", "0.1"]
91
92
93class LeakTest(LayoutTest):
94    command = ["perl", "./WebKitTools/Scripts/run-webkit-tests", "--no-launch-safari", "--no-sample-on-timeout", "--leaks", "--results-directory", "layout-test-results"]
95
96    def commandComplete(self, cmd):
97        LayoutTest.commandComplete(self, cmd)
98
99        logText = cmd.logs['stdio'].getText()
100        lines = logText.splitlines()
101        leakLines = [line for line in lines if line.find('total leaks found!') >= 0]
102        leakLines += [line for line in lines if line.find('LEAK: ') >= 0]
103        leakLines = [' '.join(x.split()[1:]) for x in leakLines]
104
105        leakSummary = {}
106        for line in leakLines:
107            count, key = line.split(' ', 1)
108            if key.find('total leaks found!') >= 0:
109                key = 'allocations found by "leaks" tool'
110
111            leakSummary[key] = leakSummary.get(key, 0) + int(count)
112
113        leakSummaryLines = []
114        for key in sorted(leakSummary.keys()):
115            leakSummaryLines.append('%s %s' % (leakSummary[key], key))
116
117        self.incorrectLayoutLines += leakSummaryLines
118
119
120class UploadLayoutResults(UploadCommand, ShellCommand):
121    name = "upload-results"
122    description = ["uploading results"]
123    descriptionDone = ["uploaded-results"]
124    command = "echo Disabled for now"
125
126    def __init__(self, *args, **kwargs):
127        ShellCommand.__init__(self, *args, **kwargs)
128
129    def setBuild(self, build):
130        ShellCommand.setBuild(self, build)
131        self.initializeForUpload()
132
133        self.command = '''
134        if [[ -d layout-test-results ]]; then \
135            find layout-test-results -type d -print0 | xargs -0 chmod ug+rx; \
136            find layout-test-results -type f -print0 | xargs -0 chmod ug+r; \
137            rsync -rlvzP --rsync-path=/home/buildresults/bin/rsync layout-test-results/ %s && rm -rf layout-test-results; \
138        fi; \
139        CRASH_LOG=~/Library/Logs/CrashReporter/DumpRenderTree*.crash*; \
140        if [[ -f $(ls -1 $CRASH_LOG | head -n 1 ) ]]; then \
141            chmod ug+r $CRASH_LOG; \
142            rsync -rlvzP --rsync-path=/home/buildresults/bin/rsync $CRASH_LOG %s && rm -rf $CRASH_LOG; \
143        fi; ''' % (self.getRemotePath(), self.getRemotePath())
144
145        self.addFactoryArguments(command=self.command)
146
147
148class CompileWebKit(Compile):
149    command = ["perl", "./WebKitTools/Scripts/build-webkit"]
150    env = {'WEBKITSUPPORTLIBRARIESZIPDIR': 'C:\\cygwin\\home\\buildbot', 'MFLAGS':''}
151    def __init__(self, *args, **kwargs):
152        configuration = kwargs.pop('configuration')
153
154        self.name = "compile-" + configuration
155        self.description = ["compiling " + configuration]
156        self.descriptionDone = ["compiled " + configuration]
157
158        Compile.__init__(self, env=self.env, *args, **kwargs)
159
160class CleanWebKit(CompileWebKit):
161    command = CompileWebKit.command + ['--clean']
162    description = ['cleaning']
163    descriptionDone = ['cleaned']
164
165class CompileWebKitNoSVG(CompileWebKit):
166    command = 'rm -rf WebKitBuild && perl ./WebKitTools/Scripts/build-webkit --no-svg'
167
168class CompileWebKitGtk(CompileWebKit):
169    command = ['perl', './WebKitTools/Scripts/build-webkit', '--gtk', '--qmake=qmake-qt4']
170
171class CleanWebKitGtk(CompileWebKitGtk):
172    command = CompileWebKitGtk.command + ['--clean']
173    description = ['cleaning']
174    descriptionDone = ['cleaned']
175
176class CompileWebKitWx(CompileWebKit):
177    command = ['perl', './WebKitTools/Scripts/build-webkit', '--wx']
178
179class CleanWebKitWx(CompileWebKitWx):
180    command = CompileWebKitWx.command + ['--clean']
181    description = ['cleaning']
182    descriptionDone = ['cleaned']
183
184class CompileWebKitWindows(UploadCommand, CompileWebKit):
185    def setBuild(self, build):
186        CompileWebKit.setBuild(self, build)
187        self.initializeForUpload()
188
189        self.command = '''\
190        ./WebKitTools/Scripts/build-webkit; \
191        RESULT=$?
192        for log in $(find WebKitBuild/*/*/*/*.htm); do \
193            chmod ug+r $log; \
194            REMOTE_NAME=$(echo $log | sed -e 's|WebKitBuild/obj/||' -e 's|/Release/|-|' -e 's|/Debug/|-|'); \
195            rsync -rlvzP --rsync-path="/home/buildresults/bin/rsync" $log %s/$REMOTE_NAME && rm $log; \
196        done; \
197        exit $RESULT;''' % (self.getRemotePath(), )
198
199        self.addFactoryArguments(command=self.command)
200
201class LayoutTestWindows(LayoutTest):
202    env = {'WEBKIT_TESTFONTS': 'C:\\cygwin\\home\\buildbot\\WebKitTestFonts'}
203
204    def __init__(self, *args, **kwargs):
205        return LayoutTest.__init__(self, env=self.env, *args, **kwargs)
206
207
208class JavaScriptCoreTestGtk(JavaScriptCoreTest):
209    command = JavaScriptCoreTest.command + ['--gtk']
210
211class JavaScriptCoreTestWx(JavaScriptCoreTest):
212    command = JavaScriptCoreTest.command + ['--wx']
213
214class LayoutTestQt(LayoutTest):
215    command  = LayoutTest.command + ['--qt']
216
217class InstallWin32Dependencies(ShellCommand):
218    description = ["installing Windows dependencies"]
219    descriptionDone = ["installed Windows dependencies"]
220    command = ["perl", "./WebKitTools/Scripts/update-webkit-auxiliary-libs"]
221
222
223# class UploadDiskImage(UploadCommand, ShellCommand):
224#     description = ["uploading disk image"]
225#     descriptionDone = ["uploaded disk image"]
226#     name = "upload-disk-image"
227
228#     def __init__(self, *args, **kwargs):
229#         UploadCommand.__init__(self, *args, **kwargs)
230#         self.command = 'umask 002 && ./WebKitTools/BuildSlaveSupport/build-launcher-app && ./WebKitTools/BuildSlaveSupport/build-launcher-dmg --upload-to-host %s' % (self.getRemotePath(), )
231#         ShellCommand.__init__(self, *args, **kwargs)
232
233class GenerateCoverageData(Compile):
234    command = ["perl", "./WebKitTools/Scripts/generate-coverage-data"]
235    description = ["generating coverage data"]
236    descriptionDone = ["generated coverage data"]
237
238
239class UploadCoverageData(UploadCommand, ShellCommand):
240    name = "upload-coverage-data"
241    description = ["uploading coverage data"]
242    descriptionDone = ["uploaded-coverage-data"]
243    command = "echo Disabled for now"
244
245    def __init__(self, *args, **kwargs):
246        ShellCommand.__init__(self, *args, **kwargs)
247
248    def setBuild(self, build):
249        ShellCommand.setBuild(self, build)
250        self.initializeForUpload()
251
252        self.command = '''\
253        if [[ -d WebKitBuild/Coverage/html ]]; then \
254            find WebKitBuild/Coverage/html -type d -print0 | xargs -0 chmod ug+rx; \
255            find WebKitBuild/Coverage/html -type f -print0 | xargs -0 chmod ug+r; \
256            rsync -rlvzP --rsync-path="/home/buildresults/bin/rsync" WebKitBuild/Coverage/html/ %s && rm -rf WebKitBuild/Coverage/html; \
257        fi;''' % (self.getRemotePath(), )
258
259        self.addFactoryArguments(command=self.command)
260
261    def getURLPath(self):
262        return "/results/code-coverage/"
263