Committed by
Gerrit Code Review
Adding Checkstyle daemon
Lazily instaniate a checkstyle daemon for the first checkstyle job. Then, each subsequent checkstyle target uses the daemon. The daemon is terminated when the parent buck or buckd exits. Change-Id: I4dbea957f20a3f77048dd25d960b7faa1eafef37
Showing
8 changed files
with
513 additions
and
41 deletions
... | @@ -110,39 +110,29 @@ def osgi_jar( | ... | @@ -110,39 +110,29 @@ def osgi_jar( |
110 | 110 | ||
111 | ### Checkstyle | 111 | ### Checkstyle |
112 | if srcs: | 112 | if srcs: |
113 | - chk_cmd = '#!/bin/bash\n' | ||
114 | base = get_base_path() | 113 | base = get_base_path() |
115 | - chk_cmd += 'OUT=$3\n' | 114 | + files = base + '\n' + '\n'.join(['%s/%s' % (base, s) for s in srcs]) |
116 | - chk_cmd += ' '.join(( 'java -jar $1', | ||
117 | - '-c $2', | ||
118 | - ' '.join(['%s/%s' % (base, s) for s in srcs]) )) | ||
119 | - chk_cmd += ' | tee $OUT' | ||
120 | - chk_cmd += ' | grep -E "^.*[0-9]+:[0-9]+: error:"' | ||
121 | - chk_cmd += ' | sed "s#^.*%s/#%s:#g"\n' % (base, name) | ||
122 | - chk_cmd += 'RESULT=(${PIPESTATUS[*]})\n' # RESULT[0] is checkstyle result, RESULT[2] is grep | ||
123 | - chk_cmd += 'test ${RESULT[2]} -eq 0 || cat $OUT\n' | ||
124 | - chk_cmd += 'rm $OUT\n' | ||
125 | - chk_cmd += 'exit ${RESULT[0]}' | ||
126 | 115 | ||
127 | genrule( | 116 | genrule( |
128 | - name = name + '-checkstyle-sh', | 117 | + name = name + '-checkstyle-files', |
129 | - bash = "echo '%s' > $OUT && chmod +x $OUT" % chk_cmd, | 118 | + bash = "echo '%s' > $OUT" % files, |
130 | srcs = srcs, | 119 | srcs = srcs, |
131 | - out = 'checkstyle.sh', | 120 | + out = 'checkstyle-files.txt', |
132 | ) | 121 | ) |
133 | 122 | ||
134 | sh_test( | 123 | sh_test( |
135 | name = name + '-checkstyle', | 124 | name = name + '-checkstyle', |
136 | - test = ':' + name + '-checkstyle-sh', | 125 | + test = '//tools/build/conf:start-checkstyle', |
137 | - args = [ | ||
138 | - '$(location //lib:checkstyle)', | ||
139 | - '$(location //tools/build/conf:checkstyle-xml)', | ||
140 | - '`mktemp /tmp/%s-checkstyle-XXXXXX`' % name, | ||
141 | - ], | ||
142 | deps = [ | 126 | deps = [ |
143 | ':'+ bare_jar_name, | 127 | ':'+ bare_jar_name, |
144 | - '//tools/build/conf:suppressions-xml', | ||
145 | ], | 128 | ], |
129 | + args = [ | ||
130 | + '$(location //tools/build/conf:checkstyle-jar)', | ||
131 | + '$(location :' + name + '-checkstyle-files)', | ||
132 | + '$(location //tools/build/conf:checkstyle-xml)', | ||
133 | + '$(location //tools/build/conf:suppressions-xml)', | ||
134 | + ], | ||
135 | + test_rule_timeout_ms = 20000, | ||
146 | labels = [ 'checkstyle' ], | 136 | labels = [ 'checkstyle' ], |
147 | ) | 137 | ) |
148 | else: | 138 | else: |
... | @@ -219,4 +209,6 @@ def osgi_jar_with_tests( | ... | @@ -219,4 +209,6 @@ def osgi_jar_with_tests( |
219 | resources = test_resources, | 209 | resources = test_resources, |
220 | resources_root = test_resources_root, | 210 | resources_root = test_resources_root, |
221 | visibility = visibility | 211 | visibility = visibility |
222 | - ) | 212 | + ) |
213 | + | ||
214 | + #FIXME need to run checkstyle on test sources | ||
... | \ No newline at end of file | ... | \ No newline at end of file | ... | ... |
1 | -# ***** This file was auto-generated at Wed May 18 14:26:50 PDT 2016. Do not edit this file manually. ***** | 1 | +# ***** This file was auto-generated at Wed May 18 17:55:44 PDT 2016. Do not edit this file manually. ***** |
2 | osgi_feature_group( | 2 | osgi_feature_group( |
3 | name = 'COMPILE', | 3 | name = 'COMPILE', |
4 | visibility = ['PUBLIC'], | 4 | visibility = ['PUBLIC'], |
... | @@ -321,6 +321,15 @@ remote_jar ( | ... | @@ -321,6 +321,15 @@ remote_jar ( |
321 | ) | 321 | ) |
322 | 322 | ||
323 | remote_jar ( | 323 | remote_jar ( |
324 | + name = 'commons-beanutils', | ||
325 | + out = 'commons-beanutils-1.9.2.jar', | ||
326 | + url = 'mvn:commons-beanutils:commons-beanutils:jar:1.9.2', | ||
327 | + sha1 = '7a87d845ad3a155297e8f67d9008f4c1e5656b71', | ||
328 | + maven_coords = 'commons-beanutils:commons-beanutils:1.9.2', | ||
329 | + visibility = [ 'PUBLIC' ], | ||
330 | +) | ||
331 | + | ||
332 | +remote_jar ( | ||
324 | name = 'concurrent-trees', | 333 | name = 'concurrent-trees', |
325 | out = 'concurrent-trees-2.4.0.jar', | 334 | out = 'concurrent-trees-2.4.0.jar', |
326 | url = 'mvn:com.googlecode.concurrent-trees:concurrent-trees:jar:2.4.0', | 335 | url = 'mvn:com.googlecode.concurrent-trees:concurrent-trees:jar:2.4.0', |
... | @@ -420,6 +429,15 @@ remote_jar ( | ... | @@ -420,6 +429,15 @@ remote_jar ( |
420 | ) | 429 | ) |
421 | 430 | ||
422 | remote_jar ( | 431 | remote_jar ( |
432 | + name = 'antlr', | ||
433 | + out = 'antlr-2.7.7.jar', | ||
434 | + url = 'mvn:antlr:antlr:jar:2.7.7', | ||
435 | + sha1 = '83cd2cd674a217ade95a4bb83a8a14f351f48bd0', | ||
436 | + maven_coords = 'antlr:antlr:jar:NON-OSGI:2.7.7', | ||
437 | + visibility = [ 'PUBLIC' ], | ||
438 | +) | ||
439 | + | ||
440 | +remote_jar ( | ||
423 | name = 'error_prone_annotations', | 441 | name = 'error_prone_annotations', |
424 | out = 'error_prone_annotations-2.0.2.jar', | 442 | out = 'error_prone_annotations-2.0.2.jar', |
425 | url = 'mvn:com.google.errorprone:error_prone_annotations:jar:2.0.2', | 443 | url = 'mvn:com.google.errorprone:error_prone_annotations:jar:2.0.2', |
... | @@ -1114,9 +1132,10 @@ remote_jar ( | ... | @@ -1114,9 +1132,10 @@ remote_jar ( |
1114 | 1132 | ||
1115 | remote_jar ( | 1133 | remote_jar ( |
1116 | name = 'checkstyle', | 1134 | name = 'checkstyle', |
1117 | - out = 'checkstyle-6.11.2-all.jar', | 1135 | + out = 'checkstyle-6.11.2.jar', |
1118 | - url = 'http://onlab.vicci.org/onos/third-party/checkstyle-6.11.2-all.jar', | 1136 | + url = 'mvn:com.puppycrawl.tools:checkstyle:jar:6.11.2', |
1119 | - sha1 = 'f504187b1743e73ffe72c2eede0ff57d45536b7d', | 1137 | + sha1 = '2705f014697ac0219de0bb2bfc33afb7ec6d22c6', |
1138 | + maven_coords = 'com.puppycrawl.tools:checkstyle:jar:NON-OSGI:6.11.2', | ||
1120 | visibility = [ 'PUBLIC' ], | 1139 | visibility = [ 'PUBLIC' ], |
1121 | ) | 1140 | ) |
1122 | 1141 | ... | ... |
... | @@ -98,6 +98,7 @@ | ... | @@ -98,6 +98,7 @@ |
98 | "catalyst-local": "mvn:io.atomix.catalyst:catalyst-local:1.0.4", | 98 | "catalyst-local": "mvn:io.atomix.catalyst:catalyst-local:1.0.4", |
99 | "catalyst-serializer": "mvn:io.atomix.catalyst:catalyst-serializer:1.0.4", | 99 | "catalyst-serializer": "mvn:io.atomix.catalyst:catalyst-serializer:1.0.4", |
100 | "catalyst-transport": "mvn:io.atomix.catalyst:catalyst-transport:1.0.4", | 100 | "catalyst-transport": "mvn:io.atomix.catalyst:catalyst-transport:1.0.4", |
101 | + "catalyst-transport": "mvn:io.atomix.catalyst:catalyst-transport:1.0.4", | ||
101 | "commons-codec": "mvn:commons-codec:commons-codec:1.10", | 102 | "commons-codec": "mvn:commons-codec:commons-codec:1.10", |
102 | "commons-collections": "mvn:commons-collections:commons-collections:3.2.2", | 103 | "commons-collections": "mvn:commons-collections:commons-collections:3.2.2", |
103 | "commons-configuration": "mvn:commons-configuration:commons-configuration:1.10", | 104 | "commons-configuration": "mvn:commons-configuration:commons-configuration:1.10", |
... | @@ -107,6 +108,7 @@ | ... | @@ -107,6 +108,7 @@ |
107 | "commons-logging": "mvn:commons-logging:commons-logging:1.1.1", | 108 | "commons-logging": "mvn:commons-logging:commons-logging:1.1.1", |
108 | "commons-math3": "mvn:org.apache.commons:commons-math3:3.6.1", | 109 | "commons-math3": "mvn:org.apache.commons:commons-math3:3.6.1", |
109 | "commons-pool": "mvn:commons-pool:commons-pool:1.6", | 110 | "commons-pool": "mvn:commons-pool:commons-pool:1.6", |
111 | + "commons-beanutils": "mvn:commons-beanutils:commons-beanutils:1.9.2", | ||
110 | "concurrent-trees": "mvn:com.googlecode.concurrent-trees:concurrent-trees:2.4.0", | 112 | "concurrent-trees": "mvn:com.googlecode.concurrent-trees:concurrent-trees:2.4.0", |
111 | "copycat-api": "mvn:org.onosproject:copycat-api:0.5.1.onos", | 113 | "copycat-api": "mvn:org.onosproject:copycat-api:0.5.1.onos", |
112 | "copycat-client": "mvn:io.atomix.copycat:copycat-client:1.0.0-rc4", | 114 | "copycat-client": "mvn:io.atomix.copycat:copycat-client:1.0.0-rc4", |
... | @@ -118,6 +120,7 @@ | ... | @@ -118,6 +120,7 @@ |
118 | "copycat-state-log": "mvn:org.onosproject:copycat-state-log:0.5.1.onos", | 120 | "copycat-state-log": "mvn:org.onosproject:copycat-state-log:0.5.1.onos", |
119 | "copycat-state-machine": "mvn:org.onosproject:copycat-state-machine:0.5.1.onos", | 121 | "copycat-state-machine": "mvn:org.onosproject:copycat-state-machine:0.5.1.onos", |
120 | "easymock": "mvn:org.easymock:easymock:3.4", | 122 | "easymock": "mvn:org.easymock:easymock:3.4", |
123 | + "antlr": "mvn:antlr:antlr:2.7.7", | ||
121 | "error_prone_annotations": "mvn:com.google.errorprone:error_prone_annotations:2.0.2", | 124 | "error_prone_annotations": "mvn:com.google.errorprone:error_prone_annotations:2.0.2", |
122 | "ganymed-ssh2": "mvn:ch.ethz.ganymed:ganymed-ssh2:262", | 125 | "ganymed-ssh2": "mvn:ch.ethz.ganymed:ganymed-ssh2:262", |
123 | "jersey-container-jetty-http": "mvn:org.glassfish.jersey.containers:jersey-container-jetty-http:2.22.2", | 126 | "jersey-container-jetty-http": "mvn:org.glassfish.jersey.containers:jersey-container-jetty-http:2.22.2", |
... | @@ -198,7 +201,7 @@ | ... | @@ -198,7 +201,7 @@ |
198 | "slf4j-jdk14": "mvn:org.slf4j:slf4j-jdk14:1.7.21", | 201 | "slf4j-jdk14": "mvn:org.slf4j:slf4j-jdk14:1.7.21", |
199 | "typesafe-config": "mvn:com.typesafe:config:1.2.1", | 202 | "typesafe-config": "mvn:com.typesafe:config:1.2.1", |
200 | "validation-api": "mvn:javax.validation:validation-api:1.1.0.Final", | 203 | "validation-api": "mvn:javax.validation:validation-api:1.1.0.Final", |
201 | - "checkstyle": "http://onlab.vicci.org/onos/third-party/checkstyle-6.11.2-all.jar", | 204 | + "checkstyle": "mvn:com.puppycrawl.tools:checkstyle:6.11.2", |
202 | "apache-karaf": "http://onlab.vicci.org/onos/third-party/apache-karaf-3.0.5.tar.gz", | 205 | "apache-karaf": "http://onlab.vicci.org/onos/third-party/apache-karaf-3.0.5.tar.gz", |
203 | "bndlib": "mvn:biz.aQute.bnd:biz.aQute.bndlib:jar:3.1.0", | 206 | "bndlib": "mvn:biz.aQute.bnd:biz.aQute.bndlib:jar:3.1.0", |
204 | "org.apache.felix.scr.bnd": { | 207 | "org.apache.felix.scr.bnd": { | ... | ... |
1 | checkstyle_source = 'src/main/resources/onos/checkstyle.xml' | 1 | checkstyle_source = 'src/main/resources/onos/checkstyle.xml' |
2 | suppression_source = 'src/main/resources/onos/suppressions.xml' | 2 | suppression_source = 'src/main/resources/onos/suppressions.xml' |
3 | 3 | ||
4 | -xml = ('<module name="SuppressionFilter">' | 4 | +export_file ( |
5 | - '<property name="file" value="$(location :suppressions-xml)"/>' | ||
6 | - '</module>' ) | ||
7 | -cmd = "sed 's#<module name=\"Checker\">#<module name=\"Checker\">%s#' %s > $OUT" % ( xml, checkstyle_source ) | ||
8 | - | ||
9 | -genrule( | ||
10 | name = 'checkstyle-xml', | 5 | name = 'checkstyle-xml', |
11 | - srcs = [ checkstyle_source ], | 6 | + src = checkstyle_source, |
12 | - out = 'checkstyle.xml', | 7 | + visibility = [ 'PUBLIC' ], |
13 | - bash = cmd, | ||
14 | - visibility = [ 'PUBLIC' ] | ||
15 | ) | 8 | ) |
16 | 9 | ||
17 | -#FIXME location suppression.xml does not trigger this rule | 10 | +export_file ( |
18 | -export_file( | ||
19 | name = 'suppressions-xml', | 11 | name = 'suppressions-xml', |
20 | src = suppression_source, | 12 | src = suppression_source, |
21 | - visibility = [ 'PUBLIC' ] | 13 | + visibility = [ 'PUBLIC' ], |
14 | +) | ||
15 | + | ||
16 | +export_file ( | ||
17 | + name = 'start-checkstyle', | ||
18 | + visibility = [ 'PUBLIC' ], | ||
19 | +) | ||
20 | + | ||
21 | +COMPILE = [ | ||
22 | + '//lib:guava', | ||
23 | + '//lib:checkstyle', | ||
24 | +] | ||
25 | + | ||
26 | +RUN = [ | ||
27 | + '//lib:commons-logging', | ||
28 | + '//lib:commons-beanutils', | ||
29 | + '//lib:commons-lang3', | ||
30 | + '//lib:commons-collections', | ||
31 | + '//lib:antlr', | ||
32 | +] | ||
33 | + | ||
34 | +java_library ( | ||
35 | + name = 'checkstyle', | ||
36 | + srcs = glob([ 'src/main/java/**/*.java' ]), | ||
37 | + deps = COMPILE, | ||
22 | ) | 38 | ) |
39 | + | ||
40 | +java_binary ( | ||
41 | + name = 'checkstyle-jar', | ||
42 | + deps = [ ':checkstyle' ] + RUN, | ||
43 | + main_class = 'org.onosproject.checkstyle.Main', | ||
44 | + blacklist = [ 'META-INF/.*' ], | ||
45 | + visibility = [ 'PUBLIC' ], | ||
46 | +) | ||
47 | + | ||
48 | +# cmd = '#!/bin/bash\n' | ||
49 | +# cmd += '$1 &>/dev/null < /dev/null &' | ||
50 | +# | ||
51 | +# genrule( | ||
52 | +# name = 'checkstyle-sh', | ||
53 | +# bash = "echo '%s' > $OUT && chmod +x $OUT" % cmd, | ||
54 | +# out = 'checkstyle.sh', | ||
55 | +# ) | ||
56 | +# | ||
57 | +# sh_test( | ||
58 | +# name = 'checkstyle-runner', | ||
59 | +# test = ':checkstyle-sh', | ||
60 | +# args = [ | ||
61 | +# '$(exe :checkstyle-jar)', | ||
62 | +# '$(location //lib:checkstyle)', | ||
63 | +# '$(location //tools/build/conf:checkstyle-xml)', | ||
64 | +# '`mktemp /tmp/%s-checkstyle-XXXXXX`', | ||
65 | +# ], | ||
66 | +# labels = [ 'checkstyle' ], | ||
67 | +# visibility = [ 'PUBLIC' ], | ||
68 | +# ) | ||
... | \ No newline at end of file | ... | \ No newline at end of file | ... | ... |
... | @@ -34,5 +34,29 @@ | ... | @@ -34,5 +34,29 @@ |
34 | <project.build.sourceEncoding>UTF-8</project.build.sourceEncoding> | 34 | <project.build.sourceEncoding>UTF-8</project.build.sourceEncoding> |
35 | </properties> | 35 | </properties> |
36 | 36 | ||
37 | + <dependencies> | ||
38 | + <dependency> | ||
39 | + <groupId>com.puppycrawl.tools</groupId> | ||
40 | + <artifactId>checkstyle</artifactId> | ||
41 | + <version>6.11.2</version> | ||
42 | + </dependency> | ||
43 | + </dependencies> | ||
44 | + | ||
45 | + <build> | ||
46 | + <plugins> | ||
47 | + <plugin> | ||
48 | + <groupId>org.apache.maven.plugins</groupId> | ||
49 | + <artifactId>maven-compiler-plugin</artifactId> | ||
50 | + <!-- TODO: update once following issue is fixed. --> | ||
51 | + <!-- https://jira.codehaus.org/browse/MCOMPILER-205 --> | ||
52 | + <version>2.5.1</version> | ||
53 | + <configuration> | ||
54 | + <source>1.8</source> | ||
55 | + <target>1.8</target> | ||
56 | + </configuration> | ||
57 | + </plugin> | ||
58 | + </plugins> | ||
59 | + </build> | ||
60 | + | ||
37 | </project> | 61 | </project> |
38 | 62 | ... | ... |
1 | +/* | ||
2 | + * Copyright 2016-present Open Networking Laboratory | ||
3 | + * | ||
4 | + * Licensed under the Apache License, Version 2.0 (the "License"); | ||
5 | + * you may not use this file except in compliance with the License. | ||
6 | + * You may obtain a copy of the License at | ||
7 | + * | ||
8 | + * http://www.apache.org/licenses/LICENSE-2.0 | ||
9 | + * | ||
10 | + * Unless required by applicable law or agreed to in writing, software | ||
11 | + * distributed under the License is distributed on an "AS IS" BASIS, | ||
12 | + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. | ||
13 | + * See the License for the specific language governing permissions and | ||
14 | + * limitations under the License. | ||
15 | + */ | ||
16 | +package org.onosproject.checkstyle; | ||
17 | + | ||
18 | +import com.google.common.io.ByteStreams; | ||
19 | +import com.puppycrawl.tools.checkstyle.Checker; | ||
20 | +import com.puppycrawl.tools.checkstyle.ConfigurationLoader; | ||
21 | +import com.puppycrawl.tools.checkstyle.DefaultConfiguration; | ||
22 | +import com.puppycrawl.tools.checkstyle.PropertiesExpander; | ||
23 | +import com.puppycrawl.tools.checkstyle.api.AuditEvent; | ||
24 | +import com.puppycrawl.tools.checkstyle.api.AuditListener; | ||
25 | +import com.puppycrawl.tools.checkstyle.api.CheckstyleException; | ||
26 | +import com.puppycrawl.tools.checkstyle.api.Configuration; | ||
27 | + | ||
28 | +import java.io.File; | ||
29 | +import java.io.IOException; | ||
30 | +import java.net.Socket; | ||
31 | +import java.util.List; | ||
32 | +import java.util.concurrent.CountDownLatch; | ||
33 | +import java.util.stream.Collectors; | ||
34 | +import java.util.stream.Stream; | ||
35 | + | ||
36 | +public class CheckstyleRunner { | ||
37 | + | ||
38 | + private final Configuration config; | ||
39 | + | ||
40 | + public CheckstyleRunner(String configLocation, String suppressionLocation) | ||
41 | + throws CheckstyleException { | ||
42 | + // create a configuration | ||
43 | + DefaultConfiguration config = (DefaultConfiguration) ConfigurationLoader.loadConfiguration( | ||
44 | + configLocation, new PropertiesExpander(System.getProperties())); | ||
45 | + | ||
46 | + // add the suppression file to the configuration | ||
47 | + DefaultConfiguration suppressions = new DefaultConfiguration("SuppressionFilter"); | ||
48 | + suppressions.addAttribute("file", suppressionLocation); | ||
49 | + config.addChild(suppressions); | ||
50 | + | ||
51 | + this.config = config; | ||
52 | + } | ||
53 | + | ||
54 | + public Runnable checkClass(Socket socket) { | ||
55 | + return () -> { | ||
56 | + try { | ||
57 | + String input = new String(ByteStreams.toByteArray(socket.getInputStream())); | ||
58 | + String output = checkClass(input); | ||
59 | + socket.getOutputStream().write(output.getBytes()); | ||
60 | + socket.getOutputStream().flush(); | ||
61 | + socket.close(); | ||
62 | + } catch (IOException e) { | ||
63 | + e.printStackTrace(); | ||
64 | + } catch (CheckstyleException e) { | ||
65 | + e.printStackTrace(); | ||
66 | + } catch (InterruptedException e) { | ||
67 | + e.printStackTrace(); | ||
68 | + } | ||
69 | + }; | ||
70 | + } | ||
71 | + | ||
72 | + public String checkClass(String input) throws CheckstyleException, InterruptedException { | ||
73 | + String[] split = input.split("\n", 2); | ||
74 | + if (split.length < 2 || split[1].length() == 0) { | ||
75 | + return ""; | ||
76 | + } | ||
77 | + String base = split[0]; | ||
78 | + String files = split[1]; | ||
79 | + | ||
80 | + // create a listener for output | ||
81 | + StringAuditor listener = new StringAuditor(); | ||
82 | + listener.setBase(base); | ||
83 | + | ||
84 | + // create Checker object and run it | ||
85 | + final Checker checker = new Checker(); | ||
86 | + final ClassLoader moduleClassLoader = Checker.class.getClassLoader(); | ||
87 | + checker.setModuleClassLoader(moduleClassLoader); | ||
88 | + | ||
89 | + try { | ||
90 | + | ||
91 | + checker.configure(config); | ||
92 | + checker.addListener(listener); | ||
93 | + | ||
94 | + // run Checker | ||
95 | + List<File> fileList = Stream.of(files.split("\n")) | ||
96 | + .map(File::new) | ||
97 | + .collect(Collectors.toList()); | ||
98 | + int errorCounter = checker.process(fileList); | ||
99 | + if (errorCounter > 0) { | ||
100 | + listener.append("CHECKSTYLE ERROR\n"); | ||
101 | + } | ||
102 | + } finally { | ||
103 | + checker.destroy(); | ||
104 | + } | ||
105 | + | ||
106 | + return listener.getAudit(); | ||
107 | + } | ||
108 | +} | ||
109 | + | ||
110 | +class StringAuditor implements AuditListener { | ||
111 | + | ||
112 | + private CountDownLatch finishedLatch = new CountDownLatch(1); | ||
113 | + private StringBuilder output = new StringBuilder(); | ||
114 | + private String base = ""; | ||
115 | + | ||
116 | + public void setBase(String base) { | ||
117 | + this.base = base; | ||
118 | + } | ||
119 | + | ||
120 | + public void append(String s) { | ||
121 | + output.append(s); | ||
122 | + } | ||
123 | + | ||
124 | + public String getAudit() throws InterruptedException { | ||
125 | + finishedLatch.await(); | ||
126 | + return output.toString(); | ||
127 | + } | ||
128 | + | ||
129 | + @Override | ||
130 | + public void auditStarted(AuditEvent evt) { | ||
131 | + | ||
132 | + } | ||
133 | + | ||
134 | + @Override | ||
135 | + public void auditFinished(AuditEvent evt) { | ||
136 | + finishedLatch.countDown(); | ||
137 | + } | ||
138 | + | ||
139 | + @Override | ||
140 | + public void fileStarted(AuditEvent evt) { | ||
141 | + | ||
142 | + } | ||
143 | + | ||
144 | + @Override | ||
145 | + public void fileFinished(AuditEvent evt) { | ||
146 | + | ||
147 | + } | ||
148 | + | ||
149 | + @Override | ||
150 | + public void addError(AuditEvent evt) { | ||
151 | + switch (evt.getSeverityLevel()) { | ||
152 | + case ERROR: | ||
153 | + String fileName = evt.getFileName(); | ||
154 | + int index = fileName.indexOf(base); | ||
155 | + if (index >= 0) { | ||
156 | + fileName = fileName.substring(index + base.length() + 1); | ||
157 | + } | ||
158 | + output.append(fileName).append(':').append(evt.getLine()); | ||
159 | + if (evt.getColumn() > 0) { | ||
160 | + output.append(':').append(evt.getColumn()); | ||
161 | + } | ||
162 | + output.append(": ").append(evt.getMessage()); | ||
163 | + output.append('\n'); | ||
164 | + break; | ||
165 | + case IGNORE: | ||
166 | + case INFO: | ||
167 | + case WARNING: | ||
168 | + default: | ||
169 | + break; | ||
170 | + } | ||
171 | + } | ||
172 | + | ||
173 | + @Override | ||
174 | + public void addException(AuditEvent evt, Throwable throwable) { | ||
175 | + addError(evt); | ||
176 | + output.append(throwable.getMessage()); | ||
177 | + } | ||
178 | +} | ||
... | \ No newline at end of file | ... | \ No newline at end of file |
1 | +/* | ||
2 | + * Copyright 2016-present Open Networking Laboratory | ||
3 | + * | ||
4 | + * Licensed under the Apache License, Version 2.0 (the "License"); | ||
5 | + * you may not use this file except in compliance with the License. | ||
6 | + * You may obtain a copy of the License at | ||
7 | + * | ||
8 | + * http://www.apache.org/licenses/LICENSE-2.0 | ||
9 | + * | ||
10 | + * Unless required by applicable law or agreed to in writing, software | ||
11 | + * distributed under the License is distributed on an "AS IS" BASIS, | ||
12 | + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. | ||
13 | + * See the License for the specific language governing permissions and | ||
14 | + * limitations under the License. | ||
15 | + */ | ||
16 | + | ||
17 | +package org.onosproject.checkstyle; | ||
18 | + | ||
19 | +import com.puppycrawl.tools.checkstyle.api.CheckstyleException; | ||
20 | + | ||
21 | +import java.io.IOException; | ||
22 | +import java.net.ServerSocket; | ||
23 | +import java.nio.ByteBuffer; | ||
24 | +import java.nio.channels.FileChannel; | ||
25 | +import java.nio.channels.FileLock; | ||
26 | +import java.nio.file.Files; | ||
27 | +import java.nio.file.Path; | ||
28 | +import java.nio.file.Paths; | ||
29 | +import java.util.Timer; | ||
30 | +import java.util.TimerTask; | ||
31 | +import java.util.concurrent.ExecutorService; | ||
32 | +import java.util.concurrent.Executors; | ||
33 | + | ||
34 | +import static java.nio.file.StandardOpenOption.*; | ||
35 | + | ||
36 | +/** | ||
37 | + * Main program for executing scenario test warden. | ||
38 | + */ | ||
39 | +public final class Main { | ||
40 | + | ||
41 | + private static long POLLING_INTERVAL = 1000; //ms | ||
42 | + | ||
43 | + // Public construction forbidden | ||
44 | + private Main(String[] args) { | ||
45 | + } | ||
46 | + | ||
47 | + /** | ||
48 | + * Main entry point for the cell warden. | ||
49 | + * | ||
50 | + * @param args command-line arguments | ||
51 | + */ | ||
52 | + public static void main(String[] args) | ||
53 | + throws CheckstyleException, IOException { | ||
54 | + startServer(args); | ||
55 | + } | ||
56 | + | ||
57 | + // Monitors another PID and exit when that process exits | ||
58 | + private static void watchProcess(String pid) { | ||
59 | + if (pid == null || pid.equals("0")) { | ||
60 | + return; | ||
61 | + } | ||
62 | + Timer timer = new Timer(true); // start as a daemon, so we don't hang shutdown | ||
63 | + timer.scheduleAtFixedRate(new TimerTask() { | ||
64 | + private String cmd = "kill -s 0 " + pid; | ||
65 | + @Override | ||
66 | + public void run() { | ||
67 | + try { | ||
68 | + Process p = Runtime.getRuntime().exec(cmd); | ||
69 | + p.waitFor(); | ||
70 | + if (p.exitValue() != 0) { | ||
71 | + System.err.println("shutting down..."); | ||
72 | + System.exit(0); | ||
73 | + } | ||
74 | + } catch (IOException | InterruptedException e) { | ||
75 | + //no-op | ||
76 | + e.printStackTrace(); | ||
77 | + } | ||
78 | + } | ||
79 | + }, POLLING_INTERVAL, POLLING_INTERVAL); | ||
80 | + } | ||
81 | + | ||
82 | + // Initiates a server. | ||
83 | + private static void startServer(String[] args) throws IOException, CheckstyleException { | ||
84 | + String portLock = args[0]; | ||
85 | + String buckPid = args[1]; | ||
86 | + String checkstyleFile = args[2]; | ||
87 | + String suppressionsFile = args[3]; | ||
88 | + | ||
89 | + // Use a file lock to ensure only one copy of the daemon runs | ||
90 | + Path portLockPath = Paths.get(portLock); | ||
91 | + FileChannel channel = FileChannel.open(portLockPath, WRITE, CREATE); | ||
92 | + FileLock lock = channel.tryLock(); | ||
93 | + if (lock == null) { | ||
94 | + System.out.println("Server is already running"); | ||
95 | + System.exit(1); | ||
96 | + } //else, hold the lock until the JVM exits | ||
97 | + | ||
98 | + // Start the server and bind it to a random port | ||
99 | + ServerSocket server = new ServerSocket(0); | ||
100 | + | ||
101 | + // Monitor the parent buck process | ||
102 | + watchProcess(buckPid); | ||
103 | + | ||
104 | + // Set up hook to clean up after ourselves | ||
105 | + Runtime.getRuntime().addShutdownHook(new Thread(() -> { | ||
106 | + try { | ||
107 | + if (channel != null) { | ||
108 | + channel.truncate(0); | ||
109 | + channel.close(); | ||
110 | + } | ||
111 | + System.err.println("tear down..."); | ||
112 | + Files.delete(portLockPath); | ||
113 | + } catch (IOException e) { | ||
114 | + //no-op: shutting down | ||
115 | + e.printStackTrace(); | ||
116 | + } | ||
117 | + })); | ||
118 | + | ||
119 | + // Write the bound port to the port file | ||
120 | + int port = server.getLocalPort(); | ||
121 | + channel.truncate(0); | ||
122 | + channel.write(ByteBuffer.wrap(Integer.toString(port).getBytes())); | ||
123 | + | ||
124 | + // Instantiate a Checkstyle runner and executor; serve until exit... | ||
125 | + CheckstyleRunner runner = new CheckstyleRunner(checkstyleFile, suppressionsFile); | ||
126 | + ExecutorService executor = Executors.newCachedThreadPool(); | ||
127 | + while (true) { | ||
128 | + try { | ||
129 | + executor.submit(runner.checkClass(server.accept())); | ||
130 | + } catch (Exception e) { | ||
131 | + e.printStackTrace(); | ||
132 | + //no-op | ||
133 | + } | ||
134 | + } | ||
135 | + } | ||
136 | +} |
tools/build/conf/start-checkstyle
0 → 100755
1 | +#!/bin/bash | ||
2 | +CHECKSTYLE=$1 | ||
3 | +FILES=$2 | ||
4 | +CONFIG=$3 | ||
5 | +SUPPRESSIONS=$4 | ||
6 | + | ||
7 | +PORT_FILE="$1.port" | ||
8 | + | ||
9 | +function ppid() { | ||
10 | + ps -p ${1:-$$} -o ppid= -o pid= -o comm= | ||
11 | +} | ||
12 | + | ||
13 | +function buck_pid() { | ||
14 | + BUCK_PID=($(ppid)) | ||
15 | + while [ ${BUCK_PID[0]} -ne 0 ]; do | ||
16 | + BUCK_PID=($(ppid $BUCK_PID)) | ||
17 | + if [ "${BUCK_PID[2]}" == "buck" ]; then | ||
18 | + # use parent PID of buck | ||
19 | + echo ${BUCK_PID[0]} | ||
20 | + return | ||
21 | + fi | ||
22 | + if [ "${BUCK_PID[2]}" == "buckd" ] || | ||
23 | + [[ "${BUCK_PID[2]}" == *"python"* ]]; then | ||
24 | + # use PID of buckd or python | ||
25 | + echo ${BUCK_PID[1]} | ||
26 | + return | ||
27 | + fi | ||
28 | + done | ||
29 | + # fallback last read PID | ||
30 | + echo ${BUCK_PID[1]} | ||
31 | +} | ||
32 | + | ||
33 | +function port() { | ||
34 | + cat $PORT_FILE 2>/dev/null || echo 0 | ||
35 | +} | ||
36 | + | ||
37 | +function check_socket() { | ||
38 | + nc localhost $(port) < /dev/null 2>/dev/null | ||
39 | + return $? | ||
40 | +} | ||
41 | + | ||
42 | +# check to see if checkstyle daemon is running; if not, start it | ||
43 | +if ! check_socket; then | ||
44 | + # Starting checkstyle server... | ||
45 | + #FIXME change to /dev/null if/when we are confident | ||
46 | + nohup java -jar $CHECKSTYLE $PORT_FILE $(buck_pid) $3 $4 >>/tmp/checkstyle.daemon 2>&1 & | ||
47 | + | ||
48 | + TRIES=20 | ||
49 | + i=0 | ||
50 | + # Wait for checkstyle server to start for 2 seconds | ||
51 | + while [ $i -lt $TRIES ]; do | ||
52 | + if check_socket; then | ||
53 | + CONNECTED=true | ||
54 | + break | ||
55 | + fi | ||
56 | + let i=i+1 | ||
57 | + sleep 0.1 | ||
58 | + done | ||
59 | + if [ -z "$CONNECTED" ]; then | ||
60 | + echo "Failed to start checkstyle server" | ||
61 | + exit 3 | ||
62 | + fi | ||
63 | +fi | ||
64 | + | ||
65 | +# run the actual checkstyle client | ||
66 | +OUT=$(cat $FILES | nc localhost $(port)) | ||
67 | +if [ $? -ne 0 ]; then | ||
68 | + echo "Error connecting to checkstyle server" | ||
69 | + exit 2 | ||
70 | +fi | ||
71 | +if [ -n "$OUT" ]; then | ||
72 | + printf "$OUT" | ||
73 | + exit 1 | ||
74 | +fi | ||
... | \ No newline at end of file | ... | \ No newline at end of file |
-
Please register or login to post a comment