randomizedtesting-release-2.1.6/000077500000000000000000000000001235451432000166675ustar00rootroot00000000000000randomizedtesting-release-2.1.6/.gitignore000066400000000000000000000001031235451432000206510ustar00rootroot00000000000000target .project .classpath .settings .idea *.versionsBackup *.swp randomizedtesting-release-2.1.6/INSTALL000066400000000000000000000004131235451432000177160ustar00rootroot00000000000000We're using Maven 3.x to reduce the size of the project. The top-level project is a parent aggregator for everything else. # Compile, test and create JAR files. mvn clean verify # Deploy a snapshot or stage a release mvn -Psonatype-oss-release,release clean deploy randomizedtesting-release-2.1.6/LICENSE000066400000000000000000000261351235451432000177030ustar00rootroot00000000000000 Apache License Version 2.0, January 2004 http://www.apache.org/licenses/ TERMS AND CONDITIONS FOR USE, REPRODUCTION, AND DISTRIBUTION 1. Definitions. "License" shall mean the terms and conditions for use, reproduction, and distribution as defined by Sections 1 through 9 of this document. "Licensor" shall mean the copyright owner or entity authorized by the copyright owner that is granting the License. "Legal Entity" shall mean the union of the acting entity and all other entities that control, are controlled by, or are under common control with that entity. For the purposes of this definition, "control" means (i) the power, direct or indirect, to cause the direction or management of such entity, whether by contract or otherwise, or (ii) ownership of fifty percent (50%) or more of the outstanding shares, or (iii) beneficial ownership of such entity. "You" (or "Your") shall mean an individual or Legal Entity exercising permissions granted by this License. "Source" form shall mean the preferred form for making modifications, including but not limited to software source code, documentation source, and configuration files. "Object" form shall mean any form resulting from mechanical transformation or translation of a Source form, including but not limited to compiled object code, generated documentation, and conversions to other media types. "Work" shall mean the work of authorship, whether in Source or Object form, made available under the License, as indicated by a copyright notice that is included in or attached to the work (an example is provided in the Appendix below). "Derivative Works" shall mean any work, whether in Source or Object form, that is based on (or derived from) the Work and for which the editorial revisions, annotations, elaborations, or other modifications represent, as a whole, an original work of authorship. For the purposes of this License, Derivative Works shall not include works that remain separable from, or merely link (or bind by name) to the interfaces of, the Work and Derivative Works thereof. "Contribution" shall mean any work of authorship, including the original version of the Work and any modifications or additions to that Work or Derivative Works thereof, that is intentionally submitted to Licensor for inclusion in the Work by the copyright owner or by an individual or Legal Entity authorized to submit on behalf of the copyright owner. For the purposes of this definition, "submitted" means any form of electronic, verbal, or written communication sent to the Licensor or its representatives, including but not limited to communication on electronic mailing lists, source code control systems, and issue tracking systems that are managed by, or on behalf of, the Licensor for the purpose of discussing and improving the Work, but excluding communication that is conspicuously marked or otherwise designated in writing by the copyright owner as "Not a Contribution." "Contributor" shall mean Licensor and any individual or Legal Entity on behalf of whom a Contribution has been received by Licensor and subsequently incorporated within the Work. 2. Grant of Copyright License. Subject to the terms and conditions of this License, each Contributor hereby grants to You a perpetual, worldwide, non-exclusive, no-charge, royalty-free, irrevocable copyright license to reproduce, prepare Derivative Works of, publicly display, publicly perform, sublicense, and distribute the Work and such Derivative Works in Source or Object form. 3. Grant of Patent License. Subject to the terms and conditions of this License, each Contributor hereby grants to You a perpetual, worldwide, non-exclusive, no-charge, royalty-free, irrevocable (except as stated in this section) patent license to make, have made, use, offer to sell, sell, import, and otherwise transfer the Work, where such license applies only to those patent claims licensable by such Contributor that are necessarily infringed by their Contribution(s) alone or by combination of their Contribution(s) with the Work to which such Contribution(s) was submitted. If You institute patent litigation against any entity (including a cross-claim or counterclaim in a lawsuit) alleging that the Work or a Contribution incorporated within the Work constitutes direct or contributory patent infringement, then any patent licenses granted to You under this License for that Work shall terminate as of the date such litigation is filed. 4. Redistribution. You may reproduce and distribute copies of the Work or Derivative Works thereof in any medium, with or without modifications, and in Source or Object form, provided that You meet the following conditions: (a) You must give any other recipients of the Work or Derivative Works a copy of this License; and (b) You must cause any modified files to carry prominent notices stating that You changed the files; and (c) You must retain, in the Source form of any Derivative Works that You distribute, all copyright, patent, trademark, and attribution notices from the Source form of the Work, excluding those notices that do not pertain to any part of the Derivative Works; and (d) If the Work includes a "NOTICE" text file as part of its distribution, then any Derivative Works that You distribute must include a readable copy of the attribution notices contained within such NOTICE file, excluding those notices that do not pertain to any part of the Derivative Works, in at least one of the following places: within a NOTICE text file distributed as part of the Derivative Works; within the Source form or documentation, if provided along with the Derivative Works; or, within a display generated by the Derivative Works, if and wherever such third-party notices normally appear. The contents of the NOTICE file are for informational purposes only and do not modify the License. You may add Your own attribution notices within Derivative Works that You distribute, alongside or as an addendum to the NOTICE text from the Work, provided that such additional attribution notices cannot be construed as modifying the License. You may add Your own copyright statement to Your modifications and may provide additional or different license terms and conditions for use, reproduction, or distribution of Your modifications, or for any such Derivative Works as a whole, provided Your use, reproduction, and distribution of the Work otherwise complies with the conditions stated in this License. 5. Submission of Contributions. Unless You explicitly state otherwise, any Contribution intentionally submitted for inclusion in the Work by You to the Licensor shall be under the terms and conditions of this License, without any additional terms or conditions. Notwithstanding the above, nothing herein shall supersede or modify the terms of any separate license agreement you may have executed with Licensor regarding such Contributions. 6. Trademarks. This License does not grant permission to use the trade names, trademarks, service marks, or product names of the Licensor, except as required for reasonable and customary use in describing the origin of the Work and reproducing the content of the NOTICE file. 7. Disclaimer of Warranty. Unless required by applicable law or agreed to in writing, Licensor provides the Work (and each Contributor provides its Contributions) on an "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied, including, without limitation, any warranties or conditions of TITLE, NON-INFRINGEMENT, MERCHANTABILITY, or FITNESS FOR A PARTICULAR PURPOSE. You are solely responsible for determining the appropriateness of using or redistributing the Work and assume any risks associated with Your exercise of permissions under this License. 8. Limitation of Liability. In no event and under no legal theory, whether in tort (including negligence), contract, or otherwise, unless required by applicable law (such as deliberate and grossly negligent acts) or agreed to in writing, shall any Contributor be liable to You for damages, including any direct, indirect, special, incidental, or consequential damages of any character arising as a result of this License or out of the use or inability to use the Work (including but not limited to damages for loss of goodwill, work stoppage, computer failure or malfunction, or any and all other commercial damages or losses), even if such Contributor has been advised of the possibility of such damages. 9. Accepting Warranty or Additional Liability. While redistributing the Work or Derivative Works thereof, You may choose to offer, and charge a fee for, acceptance of support, warranty, indemnity, or other liability obligations and/or rights consistent with this License. However, in accepting such obligations, You may act only on Your own behalf and on Your sole responsibility, not on behalf of any other Contributor, and only if You agree to indemnify, defend, and hold each Contributor harmless for any liability incurred by, or claims asserted against, such Contributor by reason of your accepting any such warranty or additional liability. END OF TERMS AND CONDITIONS APPENDIX: How to apply the Apache License to your work. To apply the Apache License to your work, attach the following boilerplate notice, with the fields enclosed by brackets "[]" replaced with your own identifying information. (Don't include the brackets!) The text should be enclosed in the appropriate comment syntax for the file format. We also recommend that a file or class name and description of purpose be included on the same "printed page" as the copyright notice for easier identification within third-party archives. Copyright [yyyy] [name of copyright owner] Licensed under the Apache License, Version 2.0 (the "License"); you may not use this file except in compliance with the License. You may obtain a copy of the License at http://www.apache.org/licenses/LICENSE-2.0 Unless required by applicable law or agreed to in writing, software distributed under the License is distributed on an "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. See the License for the specific language governing permissions and limitations under the License.randomizedtesting-release-2.1.6/README000066400000000000000000000017121235451432000175500ustar00rootroot00000000000000 JUnit extensions for testing with pseudo-randomness =================================================== randomizedtesting-runner - A JUnit runner and base classes for testing with repeatable pseudo-randomness. junit4-ant - A task for ANT for running tests in multiple JVMs, better listener support, etc. junit4-maven - A Maven plugin and mojos for running tests in multiple JVMs, better listener support, etc. This works via integration with ANT, but is seamless with maven. examples - A mini-tutorial which shows how to use randomized runner using increasingly more complex examples. Documentation ============= See http://labs.carrotsearch.com/randomizedtesting.html for some documentation (and feel free to provide patches to improve it!). A simple walk-through RandomizedRunner features is given as a set of classes under: examples/maven/src/main/java/com/carrotsearch/examples/randomizedrunner/ randomizedtesting-release-2.1.6/etc/000077500000000000000000000000001235451432000174425ustar00rootroot00000000000000randomizedtesting-release-2.1.6/etc/ant-set-formatting.xml000066400000000000000000000013771235451432000237170ustar00rootroot00000000000000 randomizedtesting-release-2.1.6/etc/eclipse/000077500000000000000000000000001235451432000210665ustar00rootroot00000000000000randomizedtesting-release-2.1.6/etc/eclipse/.settings/000077500000000000000000000000001235451432000230045ustar00rootroot00000000000000randomizedtesting-release-2.1.6/etc/eclipse/.settings/org.eclipse.jdt.core.prefs000066400000000000000000000564611235451432000300020ustar00rootroot00000000000000#Thu Jan 26 09:50:07 CET 2012 eclipse.preferences.version=1 org.eclipse.jdt.core.compiler.codegen.targetPlatform=1.6 org.eclipse.jdt.core.compiler.compliance=1.6 org.eclipse.jdt.core.compiler.problem.forbiddenReference=warning org.eclipse.jdt.core.compiler.source=1.6 org.eclipse.jdt.core.formatter.align_type_members_on_columns=false org.eclipse.jdt.core.formatter.alignment_for_arguments_in_allocation_expression=16 org.eclipse.jdt.core.formatter.alignment_for_arguments_in_annotation=0 org.eclipse.jdt.core.formatter.alignment_for_arguments_in_enum_constant=16 org.eclipse.jdt.core.formatter.alignment_for_arguments_in_explicit_constructor_call=16 org.eclipse.jdt.core.formatter.alignment_for_arguments_in_method_invocation=16 org.eclipse.jdt.core.formatter.alignment_for_arguments_in_qualified_allocation_expression=16 org.eclipse.jdt.core.formatter.alignment_for_assignment=0 org.eclipse.jdt.core.formatter.alignment_for_binary_expression=16 org.eclipse.jdt.core.formatter.alignment_for_compact_if=16 org.eclipse.jdt.core.formatter.alignment_for_conditional_expression=80 org.eclipse.jdt.core.formatter.alignment_for_enum_constants=0 org.eclipse.jdt.core.formatter.alignment_for_expressions_in_array_initializer=16 org.eclipse.jdt.core.formatter.alignment_for_method_declaration=0 org.eclipse.jdt.core.formatter.alignment_for_multiple_fields=16 org.eclipse.jdt.core.formatter.alignment_for_parameters_in_constructor_declaration=16 org.eclipse.jdt.core.formatter.alignment_for_parameters_in_method_declaration=16 org.eclipse.jdt.core.formatter.alignment_for_resources_in_try=80 org.eclipse.jdt.core.formatter.alignment_for_selector_in_method_invocation=16 org.eclipse.jdt.core.formatter.alignment_for_superclass_in_type_declaration=16 org.eclipse.jdt.core.formatter.alignment_for_superinterfaces_in_enum_declaration=16 org.eclipse.jdt.core.formatter.alignment_for_superinterfaces_in_type_declaration=16 org.eclipse.jdt.core.formatter.alignment_for_throws_clause_in_constructor_declaration=16 org.eclipse.jdt.core.formatter.alignment_for_throws_clause_in_method_declaration=16 org.eclipse.jdt.core.formatter.alignment_for_union_type_in_multicatch=16 org.eclipse.jdt.core.formatter.blank_lines_after_imports=1 org.eclipse.jdt.core.formatter.blank_lines_after_package=1 org.eclipse.jdt.core.formatter.blank_lines_before_field=0 org.eclipse.jdt.core.formatter.blank_lines_before_first_class_body_declaration=0 org.eclipse.jdt.core.formatter.blank_lines_before_imports=1 org.eclipse.jdt.core.formatter.blank_lines_before_member_type=1 org.eclipse.jdt.core.formatter.blank_lines_before_method=1 org.eclipse.jdt.core.formatter.blank_lines_before_new_chunk=1 org.eclipse.jdt.core.formatter.blank_lines_before_package=0 org.eclipse.jdt.core.formatter.blank_lines_between_import_groups=1 org.eclipse.jdt.core.formatter.blank_lines_between_type_declarations=1 org.eclipse.jdt.core.formatter.brace_position_for_annotation_type_declaration=end_of_line org.eclipse.jdt.core.formatter.brace_position_for_anonymous_type_declaration=end_of_line org.eclipse.jdt.core.formatter.brace_position_for_array_initializer=end_of_line org.eclipse.jdt.core.formatter.brace_position_for_block=end_of_line org.eclipse.jdt.core.formatter.brace_position_for_block_in_case=end_of_line org.eclipse.jdt.core.formatter.brace_position_for_constructor_declaration=end_of_line org.eclipse.jdt.core.formatter.brace_position_for_enum_constant=end_of_line org.eclipse.jdt.core.formatter.brace_position_for_enum_declaration=end_of_line org.eclipse.jdt.core.formatter.brace_position_for_method_declaration=end_of_line org.eclipse.jdt.core.formatter.brace_position_for_switch=end_of_line org.eclipse.jdt.core.formatter.brace_position_for_type_declaration=end_of_line org.eclipse.jdt.core.formatter.comment.clear_blank_lines_in_block_comment=false org.eclipse.jdt.core.formatter.comment.clear_blank_lines_in_javadoc_comment=false org.eclipse.jdt.core.formatter.comment.format_block_comments=true org.eclipse.jdt.core.formatter.comment.format_header=false org.eclipse.jdt.core.formatter.comment.format_html=true org.eclipse.jdt.core.formatter.comment.format_javadoc_comments=true org.eclipse.jdt.core.formatter.comment.format_line_comments=true org.eclipse.jdt.core.formatter.comment.format_source_code=true org.eclipse.jdt.core.formatter.comment.indent_parameter_description=true org.eclipse.jdt.core.formatter.comment.indent_root_tags=true org.eclipse.jdt.core.formatter.comment.insert_new_line_before_root_tags=insert org.eclipse.jdt.core.formatter.comment.insert_new_line_for_parameter=insert org.eclipse.jdt.core.formatter.comment.line_length=80 org.eclipse.jdt.core.formatter.comment.new_lines_at_block_boundaries=true org.eclipse.jdt.core.formatter.comment.new_lines_at_javadoc_boundaries=true org.eclipse.jdt.core.formatter.comment.preserve_white_space_between_code_and_line_comments=false org.eclipse.jdt.core.formatter.compact_else_if=true org.eclipse.jdt.core.formatter.continuation_indentation=2 org.eclipse.jdt.core.formatter.continuation_indentation_for_array_initializer=2 org.eclipse.jdt.core.formatter.disabling_tag=@formatter\:off org.eclipse.jdt.core.formatter.enabling_tag=@formatter\:on org.eclipse.jdt.core.formatter.format_guardian_clause_on_one_line=false org.eclipse.jdt.core.formatter.format_line_comment_starting_on_first_column=true org.eclipse.jdt.core.formatter.indent_body_declarations_compare_to_annotation_declaration_header=true org.eclipse.jdt.core.formatter.indent_body_declarations_compare_to_enum_constant_header=true org.eclipse.jdt.core.formatter.indent_body_declarations_compare_to_enum_declaration_header=true org.eclipse.jdt.core.formatter.indent_body_declarations_compare_to_type_header=true org.eclipse.jdt.core.formatter.indent_breaks_compare_to_cases=true org.eclipse.jdt.core.formatter.indent_empty_lines=true org.eclipse.jdt.core.formatter.indent_statements_compare_to_block=true org.eclipse.jdt.core.formatter.indent_statements_compare_to_body=true org.eclipse.jdt.core.formatter.indent_switchstatements_compare_to_cases=true org.eclipse.jdt.core.formatter.indent_switchstatements_compare_to_switch=true org.eclipse.jdt.core.formatter.indentation.size=2 org.eclipse.jdt.core.formatter.insert_new_line_after_annotation_on_field=insert org.eclipse.jdt.core.formatter.insert_new_line_after_annotation_on_local_variable=insert org.eclipse.jdt.core.formatter.insert_new_line_after_annotation_on_method=insert org.eclipse.jdt.core.formatter.insert_new_line_after_annotation_on_package=insert org.eclipse.jdt.core.formatter.insert_new_line_after_annotation_on_parameter=do not insert org.eclipse.jdt.core.formatter.insert_new_line_after_annotation_on_type=insert org.eclipse.jdt.core.formatter.insert_new_line_after_label=do not insert org.eclipse.jdt.core.formatter.insert_new_line_after_opening_brace_in_array_initializer=do not insert org.eclipse.jdt.core.formatter.insert_new_line_at_end_of_file_if_missing=do not insert org.eclipse.jdt.core.formatter.insert_new_line_before_catch_in_try_statement=do not insert org.eclipse.jdt.core.formatter.insert_new_line_before_closing_brace_in_array_initializer=do not insert org.eclipse.jdt.core.formatter.insert_new_line_before_else_in_if_statement=do not insert org.eclipse.jdt.core.formatter.insert_new_line_before_finally_in_try_statement=do not insert org.eclipse.jdt.core.formatter.insert_new_line_before_while_in_do_statement=do not insert org.eclipse.jdt.core.formatter.insert_new_line_in_empty_annotation_declaration=do not insert org.eclipse.jdt.core.formatter.insert_new_line_in_empty_anonymous_type_declaration=do not insert org.eclipse.jdt.core.formatter.insert_new_line_in_empty_block=do not insert org.eclipse.jdt.core.formatter.insert_new_line_in_empty_enum_constant=do not insert org.eclipse.jdt.core.formatter.insert_new_line_in_empty_enum_declaration=do not insert org.eclipse.jdt.core.formatter.insert_new_line_in_empty_method_body=do not insert org.eclipse.jdt.core.formatter.insert_new_line_in_empty_type_declaration=do not insert org.eclipse.jdt.core.formatter.insert_space_after_and_in_type_parameter=insert org.eclipse.jdt.core.formatter.insert_space_after_assignment_operator=insert org.eclipse.jdt.core.formatter.insert_space_after_at_in_annotation=do not insert org.eclipse.jdt.core.formatter.insert_space_after_at_in_annotation_type_declaration=do not insert org.eclipse.jdt.core.formatter.insert_space_after_binary_operator=insert org.eclipse.jdt.core.formatter.insert_space_after_closing_angle_bracket_in_type_arguments=insert org.eclipse.jdt.core.formatter.insert_space_after_closing_angle_bracket_in_type_parameters=insert org.eclipse.jdt.core.formatter.insert_space_after_closing_brace_in_block=insert org.eclipse.jdt.core.formatter.insert_space_after_closing_paren_in_cast=insert org.eclipse.jdt.core.formatter.insert_space_after_colon_in_assert=insert org.eclipse.jdt.core.formatter.insert_space_after_colon_in_case=insert org.eclipse.jdt.core.formatter.insert_space_after_colon_in_conditional=insert org.eclipse.jdt.core.formatter.insert_space_after_colon_in_for=insert org.eclipse.jdt.core.formatter.insert_space_after_colon_in_labeled_statement=insert org.eclipse.jdt.core.formatter.insert_space_after_comma_in_allocation_expression=insert org.eclipse.jdt.core.formatter.insert_space_after_comma_in_annotation=insert org.eclipse.jdt.core.formatter.insert_space_after_comma_in_array_initializer=insert org.eclipse.jdt.core.formatter.insert_space_after_comma_in_constructor_declaration_parameters=insert org.eclipse.jdt.core.formatter.insert_space_after_comma_in_constructor_declaration_throws=insert org.eclipse.jdt.core.formatter.insert_space_after_comma_in_enum_constant_arguments=insert org.eclipse.jdt.core.formatter.insert_space_after_comma_in_enum_declarations=insert org.eclipse.jdt.core.formatter.insert_space_after_comma_in_explicitconstructorcall_arguments=insert org.eclipse.jdt.core.formatter.insert_space_after_comma_in_for_increments=insert org.eclipse.jdt.core.formatter.insert_space_after_comma_in_for_inits=insert org.eclipse.jdt.core.formatter.insert_space_after_comma_in_method_declaration_parameters=insert org.eclipse.jdt.core.formatter.insert_space_after_comma_in_method_declaration_throws=insert org.eclipse.jdt.core.formatter.insert_space_after_comma_in_method_invocation_arguments=insert org.eclipse.jdt.core.formatter.insert_space_after_comma_in_multiple_field_declarations=insert org.eclipse.jdt.core.formatter.insert_space_after_comma_in_multiple_local_declarations=insert org.eclipse.jdt.core.formatter.insert_space_after_comma_in_parameterized_type_reference=do not insert org.eclipse.jdt.core.formatter.insert_space_after_comma_in_superinterfaces=insert org.eclipse.jdt.core.formatter.insert_space_after_comma_in_type_arguments=do not insert org.eclipse.jdt.core.formatter.insert_space_after_comma_in_type_parameters=do not insert org.eclipse.jdt.core.formatter.insert_space_after_ellipsis=insert org.eclipse.jdt.core.formatter.insert_space_after_opening_angle_bracket_in_parameterized_type_reference=do not insert org.eclipse.jdt.core.formatter.insert_space_after_opening_angle_bracket_in_type_arguments=do not insert org.eclipse.jdt.core.formatter.insert_space_after_opening_angle_bracket_in_type_parameters=do not insert org.eclipse.jdt.core.formatter.insert_space_after_opening_brace_in_array_initializer=do not insert org.eclipse.jdt.core.formatter.insert_space_after_opening_bracket_in_array_allocation_expression=do not insert org.eclipse.jdt.core.formatter.insert_space_after_opening_bracket_in_array_reference=do not insert org.eclipse.jdt.core.formatter.insert_space_after_opening_paren_in_annotation=do not insert org.eclipse.jdt.core.formatter.insert_space_after_opening_paren_in_cast=do not insert org.eclipse.jdt.core.formatter.insert_space_after_opening_paren_in_catch=do not insert org.eclipse.jdt.core.formatter.insert_space_after_opening_paren_in_constructor_declaration=do not insert org.eclipse.jdt.core.formatter.insert_space_after_opening_paren_in_enum_constant=do not insert org.eclipse.jdt.core.formatter.insert_space_after_opening_paren_in_for=do not insert org.eclipse.jdt.core.formatter.insert_space_after_opening_paren_in_if=do not insert org.eclipse.jdt.core.formatter.insert_space_after_opening_paren_in_method_declaration=do not insert org.eclipse.jdt.core.formatter.insert_space_after_opening_paren_in_method_invocation=do not insert org.eclipse.jdt.core.formatter.insert_space_after_opening_paren_in_parenthesized_expression=do not insert org.eclipse.jdt.core.formatter.insert_space_after_opening_paren_in_switch=do not insert org.eclipse.jdt.core.formatter.insert_space_after_opening_paren_in_synchronized=do not insert org.eclipse.jdt.core.formatter.insert_space_after_opening_paren_in_try=do not insert org.eclipse.jdt.core.formatter.insert_space_after_opening_paren_in_while=do not insert org.eclipse.jdt.core.formatter.insert_space_after_postfix_operator=do not insert org.eclipse.jdt.core.formatter.insert_space_after_prefix_operator=do not insert org.eclipse.jdt.core.formatter.insert_space_after_question_in_conditional=insert org.eclipse.jdt.core.formatter.insert_space_after_question_in_wildcard=do not insert org.eclipse.jdt.core.formatter.insert_space_after_semicolon_in_for=insert org.eclipse.jdt.core.formatter.insert_space_after_semicolon_in_try_resources=insert org.eclipse.jdt.core.formatter.insert_space_after_unary_operator=do not insert org.eclipse.jdt.core.formatter.insert_space_before_and_in_type_parameter=insert org.eclipse.jdt.core.formatter.insert_space_before_assignment_operator=insert org.eclipse.jdt.core.formatter.insert_space_before_at_in_annotation_type_declaration=insert org.eclipse.jdt.core.formatter.insert_space_before_binary_operator=insert org.eclipse.jdt.core.formatter.insert_space_before_closing_angle_bracket_in_parameterized_type_reference=do not insert org.eclipse.jdt.core.formatter.insert_space_before_closing_angle_bracket_in_type_arguments=do not insert org.eclipse.jdt.core.formatter.insert_space_before_closing_angle_bracket_in_type_parameters=do not insert org.eclipse.jdt.core.formatter.insert_space_before_closing_brace_in_array_initializer=do not insert org.eclipse.jdt.core.formatter.insert_space_before_closing_bracket_in_array_allocation_expression=do not insert org.eclipse.jdt.core.formatter.insert_space_before_closing_bracket_in_array_reference=do not insert org.eclipse.jdt.core.formatter.insert_space_before_closing_paren_in_annotation=do not insert org.eclipse.jdt.core.formatter.insert_space_before_closing_paren_in_cast=do not insert org.eclipse.jdt.core.formatter.insert_space_before_closing_paren_in_catch=do not insert org.eclipse.jdt.core.formatter.insert_space_before_closing_paren_in_constructor_declaration=do not insert org.eclipse.jdt.core.formatter.insert_space_before_closing_paren_in_enum_constant=do not insert org.eclipse.jdt.core.formatter.insert_space_before_closing_paren_in_for=do not insert org.eclipse.jdt.core.formatter.insert_space_before_closing_paren_in_if=do not insert org.eclipse.jdt.core.formatter.insert_space_before_closing_paren_in_method_declaration=do not insert org.eclipse.jdt.core.formatter.insert_space_before_closing_paren_in_method_invocation=do not insert org.eclipse.jdt.core.formatter.insert_space_before_closing_paren_in_parenthesized_expression=do not insert org.eclipse.jdt.core.formatter.insert_space_before_closing_paren_in_switch=do not insert org.eclipse.jdt.core.formatter.insert_space_before_closing_paren_in_synchronized=do not insert org.eclipse.jdt.core.formatter.insert_space_before_closing_paren_in_try=do not insert org.eclipse.jdt.core.formatter.insert_space_before_closing_paren_in_while=do not insert org.eclipse.jdt.core.formatter.insert_space_before_colon_in_assert=insert org.eclipse.jdt.core.formatter.insert_space_before_colon_in_case=do not insert org.eclipse.jdt.core.formatter.insert_space_before_colon_in_conditional=insert org.eclipse.jdt.core.formatter.insert_space_before_colon_in_default=do not insert org.eclipse.jdt.core.formatter.insert_space_before_colon_in_for=insert org.eclipse.jdt.core.formatter.insert_space_before_colon_in_labeled_statement=do not insert org.eclipse.jdt.core.formatter.insert_space_before_comma_in_allocation_expression=do not insert org.eclipse.jdt.core.formatter.insert_space_before_comma_in_annotation=do not insert org.eclipse.jdt.core.formatter.insert_space_before_comma_in_array_initializer=do not insert org.eclipse.jdt.core.formatter.insert_space_before_comma_in_constructor_declaration_parameters=do not insert org.eclipse.jdt.core.formatter.insert_space_before_comma_in_constructor_declaration_throws=do not insert org.eclipse.jdt.core.formatter.insert_space_before_comma_in_enum_constant_arguments=do not insert org.eclipse.jdt.core.formatter.insert_space_before_comma_in_enum_declarations=do not insert org.eclipse.jdt.core.formatter.insert_space_before_comma_in_explicitconstructorcall_arguments=do not insert org.eclipse.jdt.core.formatter.insert_space_before_comma_in_for_increments=do not insert org.eclipse.jdt.core.formatter.insert_space_before_comma_in_for_inits=do not insert org.eclipse.jdt.core.formatter.insert_space_before_comma_in_method_declaration_parameters=do not insert org.eclipse.jdt.core.formatter.insert_space_before_comma_in_method_declaration_throws=do not insert org.eclipse.jdt.core.formatter.insert_space_before_comma_in_method_invocation_arguments=do not insert org.eclipse.jdt.core.formatter.insert_space_before_comma_in_multiple_field_declarations=do not insert org.eclipse.jdt.core.formatter.insert_space_before_comma_in_multiple_local_declarations=do not insert org.eclipse.jdt.core.formatter.insert_space_before_comma_in_parameterized_type_reference=do not insert org.eclipse.jdt.core.formatter.insert_space_before_comma_in_superinterfaces=do not insert org.eclipse.jdt.core.formatter.insert_space_before_comma_in_type_arguments=do not insert org.eclipse.jdt.core.formatter.insert_space_before_comma_in_type_parameters=do not insert org.eclipse.jdt.core.formatter.insert_space_before_ellipsis=do not insert org.eclipse.jdt.core.formatter.insert_space_before_opening_angle_bracket_in_parameterized_type_reference=do not insert org.eclipse.jdt.core.formatter.insert_space_before_opening_angle_bracket_in_type_arguments=do not insert org.eclipse.jdt.core.formatter.insert_space_before_opening_angle_bracket_in_type_parameters=do not insert org.eclipse.jdt.core.formatter.insert_space_before_opening_brace_in_annotation_type_declaration=insert org.eclipse.jdt.core.formatter.insert_space_before_opening_brace_in_anonymous_type_declaration=insert org.eclipse.jdt.core.formatter.insert_space_before_opening_brace_in_array_initializer=insert org.eclipse.jdt.core.formatter.insert_space_before_opening_brace_in_block=insert org.eclipse.jdt.core.formatter.insert_space_before_opening_brace_in_constructor_declaration=insert org.eclipse.jdt.core.formatter.insert_space_before_opening_brace_in_enum_constant=insert org.eclipse.jdt.core.formatter.insert_space_before_opening_brace_in_enum_declaration=insert org.eclipse.jdt.core.formatter.insert_space_before_opening_brace_in_method_declaration=insert org.eclipse.jdt.core.formatter.insert_space_before_opening_brace_in_switch=insert org.eclipse.jdt.core.formatter.insert_space_before_opening_brace_in_type_declaration=insert org.eclipse.jdt.core.formatter.insert_space_before_opening_bracket_in_array_allocation_expression=do not insert org.eclipse.jdt.core.formatter.insert_space_before_opening_bracket_in_array_reference=do not insert org.eclipse.jdt.core.formatter.insert_space_before_opening_bracket_in_array_type_reference=do not insert org.eclipse.jdt.core.formatter.insert_space_before_opening_paren_in_annotation=do not insert org.eclipse.jdt.core.formatter.insert_space_before_opening_paren_in_annotation_type_member_declaration=do not insert org.eclipse.jdt.core.formatter.insert_space_before_opening_paren_in_catch=insert org.eclipse.jdt.core.formatter.insert_space_before_opening_paren_in_constructor_declaration=do not insert org.eclipse.jdt.core.formatter.insert_space_before_opening_paren_in_enum_constant=do not insert org.eclipse.jdt.core.formatter.insert_space_before_opening_paren_in_for=insert org.eclipse.jdt.core.formatter.insert_space_before_opening_paren_in_if=insert org.eclipse.jdt.core.formatter.insert_space_before_opening_paren_in_method_declaration=do not insert org.eclipse.jdt.core.formatter.insert_space_before_opening_paren_in_method_invocation=do not insert org.eclipse.jdt.core.formatter.insert_space_before_opening_paren_in_parenthesized_expression=do not insert org.eclipse.jdt.core.formatter.insert_space_before_opening_paren_in_switch=insert org.eclipse.jdt.core.formatter.insert_space_before_opening_paren_in_synchronized=insert org.eclipse.jdt.core.formatter.insert_space_before_opening_paren_in_try=insert org.eclipse.jdt.core.formatter.insert_space_before_opening_paren_in_while=insert org.eclipse.jdt.core.formatter.insert_space_before_parenthesized_expression_in_return=insert org.eclipse.jdt.core.formatter.insert_space_before_parenthesized_expression_in_throw=insert org.eclipse.jdt.core.formatter.insert_space_before_postfix_operator=do not insert org.eclipse.jdt.core.formatter.insert_space_before_prefix_operator=do not insert org.eclipse.jdt.core.formatter.insert_space_before_question_in_conditional=insert org.eclipse.jdt.core.formatter.insert_space_before_question_in_wildcard=do not insert org.eclipse.jdt.core.formatter.insert_space_before_semicolon=do not insert org.eclipse.jdt.core.formatter.insert_space_before_semicolon_in_for=do not insert org.eclipse.jdt.core.formatter.insert_space_before_semicolon_in_try_resources=do not insert org.eclipse.jdt.core.formatter.insert_space_before_unary_operator=do not insert org.eclipse.jdt.core.formatter.insert_space_between_brackets_in_array_type_reference=do not insert org.eclipse.jdt.core.formatter.insert_space_between_empty_braces_in_array_initializer=do not insert org.eclipse.jdt.core.formatter.insert_space_between_empty_brackets_in_array_allocation_expression=do not insert org.eclipse.jdt.core.formatter.insert_space_between_empty_parens_in_annotation_type_member_declaration=do not insert org.eclipse.jdt.core.formatter.insert_space_between_empty_parens_in_constructor_declaration=do not insert org.eclipse.jdt.core.formatter.insert_space_between_empty_parens_in_enum_constant=do not insert org.eclipse.jdt.core.formatter.insert_space_between_empty_parens_in_method_declaration=do not insert org.eclipse.jdt.core.formatter.insert_space_between_empty_parens_in_method_invocation=do not insert org.eclipse.jdt.core.formatter.join_lines_in_comments=true org.eclipse.jdt.core.formatter.join_wrapped_lines=true org.eclipse.jdt.core.formatter.keep_else_statement_on_same_line=true org.eclipse.jdt.core.formatter.keep_empty_array_initializer_on_one_line=false org.eclipse.jdt.core.formatter.keep_imple_if_on_one_line=false org.eclipse.jdt.core.formatter.keep_then_statement_on_same_line=true org.eclipse.jdt.core.formatter.lineSplit=100 org.eclipse.jdt.core.formatter.never_indent_block_comments_on_first_column=false org.eclipse.jdt.core.formatter.never_indent_line_comments_on_first_column=false org.eclipse.jdt.core.formatter.number_of_blank_lines_at_beginning_of_method_body=0 org.eclipse.jdt.core.formatter.number_of_empty_lines_to_preserve=1 org.eclipse.jdt.core.formatter.put_empty_statement_on_new_line=true org.eclipse.jdt.core.formatter.tabulation.char=space org.eclipse.jdt.core.formatter.tabulation.size=2 org.eclipse.jdt.core.formatter.use_on_off_tags=true org.eclipse.jdt.core.formatter.use_tabs_only_for_leading_indentations=true org.eclipse.jdt.core.formatter.wrap_before_binary_operator=true org.eclipse.jdt.core.formatter.wrap_before_or_operator_multicatch=true org.eclipse.jdt.core.formatter.wrap_outer_expressions_when_nested=true randomizedtesting-release-2.1.6/etc/eclipse/.settings/org.eclipse.jdt.ui.prefs000066400000000000000000000002271235451432000274540ustar00rootroot00000000000000#Thu Jan 26 09:50:07 CET 2012 eclipse.preferences.version=1 formatter_profile=org.eclipse.jdt.ui.default.eclipse_profile formatter_settings_version=12 randomizedtesting-release-2.1.6/etc/javadoc/000077500000000000000000000000001235451432000210515ustar00rootroot00000000000000randomizedtesting-release-2.1.6/etc/javadoc/google-guava/000077500000000000000000000000001235451432000234265ustar00rootroot00000000000000randomizedtesting-release-2.1.6/etc/javadoc/google-guava/package-list000066400000000000000000000004141235451432000257140ustar00rootroot00000000000000com.google.common.annotations com.google.common.base com.google.common.base.internal com.google.common.cache com.google.common.collect com.google.common.eventbus com.google.common.io com.google.common.net com.google.common.primitives com.google.common.util.concurrent randomizedtesting-release-2.1.6/etc/javadoc/junit/000077500000000000000000000000001235451432000222025ustar00rootroot00000000000000randomizedtesting-release-2.1.6/etc/javadoc/junit/package-list000066400000000000000000000006651235451432000245000ustar00rootroot00000000000000org.hamcrest org.hamcrest.core org.hamcrest.internal org.junit org.junit.experimental org.junit.experimental.categories org.junit.experimental.max org.junit.experimental.results org.junit.experimental.runners org.junit.experimental.theories org.junit.experimental.theories.suppliers org.junit.matchers org.junit.rules org.junit.runner org.junit.runner.manipulation org.junit.runner.notification org.junit.runners org.junit.runners.model randomizedtesting-release-2.1.6/examples/000077500000000000000000000000001235451432000205055ustar00rootroot00000000000000randomizedtesting-release-2.1.6/examples/ant/000077500000000000000000000000001235451432000212675ustar00rootroot00000000000000randomizedtesting-release-2.1.6/examples/ant/build.xml000066400000000000000000000145331235451432000231160ustar00rootroot00000000000000 Done. See reports under target/. randomizedtesting-release-2.1.6/examples/ant/pom.xml000066400000000000000000000107671235451432000226170ustar00rootroot00000000000000 4.0.0 com.carrotsearch.randomizedtesting randomizedtesting-parent 2.1.6 ../../pom.xml randomizedtesting-examples-ant RandomizedTesting ANT Examples Simple use-case examples meant to be included in some end-user documentation if it's ever going to be written... true com.carrotsearch.randomizedtesting randomizedtesting-examples ${project.version} compile com.carrotsearch.randomizedtesting junit4-ant ${project.version} compile org.eclipse.m2e lifecycle-mapping 1.0.0 org.apache.maven.plugins maven-dependency-plugin [1.0.0,) copy-dependencies org.apache.maven.plugins maven-dependency-plugin copy-dependencies integration-test copy-dependencies ${basedir}/target/lib org.apache.maven.plugins maven-antrun-plugin ant-run-tests integration-test run tools.jar ${java.home}/../lib/tools.jar org.apache.maven.plugins maven-antrun-plugin com.sun tools 1.5.0 system ${java.home}/../lib/tools.jar randomizedtesting-release-2.1.6/examples/maven/000077500000000000000000000000001235451432000216135ustar00rootroot00000000000000randomizedtesting-release-2.1.6/examples/maven/pom.xml000066400000000000000000000065161235451432000231400ustar00rootroot00000000000000 4.0.0 com.carrotsearch.randomizedtesting randomizedtesting-parent 2.1.6 ../../pom.xml randomizedtesting-examples RandomizedTesting Examples Simple use-case examples meant to be included in some end-user documentation if it's ever going to be written... false com.carrotsearch.randomizedtesting randomizedtesting-runner ${project.version} compile junit junit compile org.apache.maven.plugins maven-surefire-plugin true com.carrotsearch.randomizedtesting junit4-maven-plugin ${project.version} junit4-tests junit4 test false ${project.build.outputDirectory} randomizedtesting-release-2.1.6/examples/maven/src/000077500000000000000000000000001235451432000224025ustar00rootroot00000000000000randomizedtesting-release-2.1.6/examples/maven/src/main/000077500000000000000000000000001235451432000233265ustar00rootroot00000000000000randomizedtesting-release-2.1.6/examples/maven/src/main/java/000077500000000000000000000000001235451432000242475ustar00rootroot00000000000000randomizedtesting-release-2.1.6/examples/maven/src/main/java/com/000077500000000000000000000000001235451432000250255ustar00rootroot00000000000000randomizedtesting-release-2.1.6/examples/maven/src/main/java/com/carrotsearch/000077500000000000000000000000001235451432000275055ustar00rootroot00000000000000randomizedtesting-release-2.1.6/examples/maven/src/main/java/com/carrotsearch/examples/000077500000000000000000000000001235451432000313235ustar00rootroot00000000000000000077500000000000000000000000001235451432000346325ustar00rootroot00000000000000randomizedtesting-release-2.1.6/examples/maven/src/main/java/com/carrotsearch/examples/randomizedrunnerTest001SimpleUseCase.java000066400000000000000000000017501235451432000412630ustar00rootroot00000000000000randomizedtesting-release-2.1.6/examples/maven/src/main/java/com/carrotsearch/examples/randomizedrunnerpackage com.carrotsearch.examples.randomizedrunner; import org.junit.Before; import org.junit.Test; import org.junit.runner.RunWith; import com.carrotsearch.randomizedtesting.RandomizedRunner; /** * This is a test-based tutorial introducing to randomized JUnit testing using * {@link RandomizedRunner}. Follow test cases in their alphabetic order. * *

One way to start using {@link RandomizedRunner} is to declare * your suite class as being executed by {@link RandomizedRunner} (using * {@link RunWith} annotation). The {@link #success()} method doesn't do anything * useful but runs under {@link RandomizedRunner}. We know this for sure because we * can hide a hook {@link #before()} method to be private * (and normal JUnit doesn't allow this). */ @RunWith(RandomizedRunner.class) public class Test001SimpleUseCase { @Before private void before() { // Ha! This won't work under the default JUnit runner. } @Test public void success() { // Do nothing. } } Test002ExtendingRandomizedTest.java000066400000000000000000000023271235451432000433650ustar00rootroot00000000000000randomizedtesting-release-2.1.6/examples/maven/src/main/java/com/carrotsearch/examples/randomizedrunnerpackage com.carrotsearch.examples.randomizedrunner; import java.util.Random; import org.junit.Test; import com.carrotsearch.randomizedtesting.RandomizedContext; import com.carrotsearch.randomizedtesting.RandomizedTest; /** * To start using pseudo-randomization we need to get hold of the * {@link RandomizedContext} instance associated with the test. This can be done * manually, as shown in {@link #getContextByHand()} method or (better) we can * extend {@link RandomizedTest} and have a superclass method to handle this * (and more) for us as shown in {#link #getContextFromSuper()} * *

Note that {@link Random} instances acquired from the context are * preinitialized with a repeatable seed (we'll get to that) so tests * can be re-run with the same random sequence if something fails. */ public class Test002ExtendingRandomizedTest extends RandomizedTest { @Test public void getContextByHand() { RandomizedContext context = RandomizedContext.current(); Random rnd = context.getRandom(); System.out.println("Random, next int: " + rnd.nextInt()); } @Test public void getContextFromSuper() { Random rnd = super.getRandom(); System.out.println("Random, next int: " + rnd.nextInt()); } } Test003UsingRandomness.java000066400000000000000000000066121235451432000417040ustar00rootroot00000000000000randomizedtesting-release-2.1.6/examples/maven/src/main/java/com/carrotsearch/examples/randomizedrunnerpackage com.carrotsearch.examples.randomizedrunner; import java.util.Random; import org.junit.Test; import com.carrotsearch.randomizedtesting.RandomizedRunner; import com.carrotsearch.randomizedtesting.RandomizedTest; /** * So far we haven't really used the {@link Random} provided by * {@link RandomizedRunner}. The idea behind randomized tests is to, for each * test execution: *

* *

* Let's see this on a simple example of a method that adds two * integers ({@link Adder#add(int, int)}). We can test this method using a "fixed" test * case as shown in {@link #fixedTesting} but this test will always execute in * an identical way (which is good if you're looking for regression coverage but * bad if you want to expand your tested domain). * *

* A randomized test, on the other hand, will pick parameters from a larger * spectrum of values and assert on the method's contract. Here, we can make * sure the sum is always larger or equal than the arguments given two positive * arguments. This assertion will fail quite often because of integer overflows as shown * in {@link #randomizedTesting()} (re-run the test a few times if it doesn't * fail the first time). * *

* While the above example is trivial most of the bugs in code stem from similar * subtleties (possibly resulting from more complex interactions). In many cases * the "contract" that we can assert on can be stated as "throw no-exception" given * valid arguments. An example of that is in method {@link #expectNoException()}. * At first glance this method will work most of the time, but try passing * {@link Integer#MIN_VALUE} as a random number and see what will happen. */ public class Test003UsingRandomness extends RandomizedTest { public static class Adder { //[[[start:adder]]] /** * This method adds a and b and returns their sum. */ public static int add(int a, int b) { return a + b; } //[[[end:adder]]] } //[[[start:adder-fixed]]] @Test public void fixedTesting() { // Note how we use superclass methods, RandomizedTest extends from // Assert so these methods are readily available. assertEquals( 4, Adder.add(2, 2)); assertEquals(-1, Adder.add(0, -1)); assertEquals( 0, Adder.add(0, 0)); } //[[[end:adder-fixed]]] //[[[start:adder-randomized]]] @Test public void randomizedTesting() { // Here we pick two positive integers. Note superclass utility methods. int a = randomIntBetween(0, Integer.MAX_VALUE); int b = randomIntBetween(0, Integer.MAX_VALUE); int result = Adder.add(a, b); assertTrue(result + " < (" + a + " or " + b + ")?", result >= a && result >= b); } //[[[end:adder-randomized]]] @Test public void expectNoException() { String [] words = {"oh", "my", "this", "is", "bad."}; // This will pick a random word from the array above... System.out.println(words[Math.abs(randomInt()) % words.length]); // .. unless the random picked happens to be this number (fixed to get // a reproducible example, but you get the idea); System.out.println(words[Math.abs(Integer.MIN_VALUE) % words.length]); } } Test004MoreRandomness.java000066400000000000000000000071521235451432000415220ustar00rootroot00000000000000randomizedtesting-release-2.1.6/examples/maven/src/main/java/com/carrotsearch/examples/randomizedrunnerpackage com.carrotsearch.examples.randomizedrunner; import java.util.Random; import org.junit.AfterClass; import org.junit.Test; import org.junit.runner.Description; import org.junit.runner.RunWith; import org.junit.runners.Suite; import org.junit.runners.Suite.SuiteClasses; import com.carrotsearch.randomizedtesting.RandomizedContext; import com.carrotsearch.randomizedtesting.RandomizedRunner; import com.carrotsearch.randomizedtesting.RandomizedTest; import com.carrotsearch.randomizedtesting.SysGlobals; import com.carrotsearch.randomizedtesting.annotations.Seed; import com.carrotsearch.randomizedtesting.annotations.Seeds; /** * Randomness is entwined everywhere in {@link RandomizedRunner}. An instance of * {@link Random} is of course available from a {@link RandomizedContext}, but * even tests themselves are randomized, or to be more precise: their order of * execution is shuffled. * *

* In this example we have two classes that contain three methods (they're nested * under a single suite class for simplicity). Every execution of class * {@link Test004MoreRandomness.OrderRandomized} will be different, shuffling * test methods around (and the random numbers written to the output). * We can "pin" the execution order by forcing the master random * seed using {@link Seed} annotation on the class (or a system property * {@link SysGlobals#SYSPROP_RANDOM_SEED}). Doing so also fixes all derivative random * generators in all tests - this is shown in * {@link Test004MoreRandomness.OrderRandomizedButFixed}, every execution of this * class will be identical (and will emit identical pseudo-random numbers). * *

* All this is meant for one purpose: help in reproducing a failed randomized test * case. Once a test case fails, make sure you write down the random seed number * that caused the failure and add appropriate {@link Seeds} annotation on the method * that failed like so: *

 * {@literal @}{@link Seeds}({
 *   {@literal @}{@link Seed}("012345"),
 *   {@literal @}{@link Seed}()
 * })
 * 
* where 012345 is the replaced by the seed that caused the failure. This makes * the test methods run with a fixed seed once and then with a random seed again, * easily creating a new regression test so that the bug does not reoccur in the * future. An example of that is shown in * {@link Test004MoreRandomness.OrderRegression#regression()}. Also note * how {@link RandomizedRunner} modifies test method names for such "expanded" methods, appending * the random seed as a parameter. This is needed to avoid duplicate * test {@link Description} objects (a design flaw in JUnit). We will see these parameters * again in the example concerning parameterized tests. */ @RunWith(Suite.class) @SuiteClasses({ Test004MoreRandomness.OrderRandomized.class, Test004MoreRandomness.OrderRandomizedButFixed.class, Test004MoreRandomness.OrderRegression.class }) public class Test004MoreRandomness { public static class OrderRandomized extends RandomizedTest { @Test public void method1() { System.out.println("method1, " + randomInt()); } @Test public void method2() { System.out.println("method2, " + randomInt()); } @Test public void method3() { System.out.println("method3, " + randomInt()); } @AfterClass public static void empty() { System.out.println("--"); } } @Seed("deadbeef") public static class OrderRandomizedButFixed extends OrderRandomized { } public static class OrderRegression extends RandomizedTest { @Seeds({ @Seed("deadbeef"), @Seed() }) @Test public void regression() { System.out.println("regression, " + randomInt()); } } } Test005RecoveringRandomSeed.java000066400000000000000000000073121235451432000426320ustar00rootroot00000000000000randomizedtesting-release-2.1.6/examples/maven/src/main/java/com/carrotsearch/examples/randomizedrunnerpackage com.carrotsearch.examples.randomizedrunner; import java.util.Random; import org.junit.*; import com.carrotsearch.randomizedtesting.*; import com.carrotsearch.randomizedtesting.annotations.Repeat; import com.carrotsearch.randomizedtesting.annotations.Seed; /** * {@link RandomizedRunner} uses several "contexts", each of which is assigned a * predictable {@link Random} and is modeled using a {@link Randomness} * instance. The "suite" or "master" context is available from * {@link BeforeClass} or {@link AfterClass} hooks, for example. Each test * method has a nested context with a random seed derived from the master. This * way even though the order of tests is shuffled and each test can make a * random number of calls to its own context's {@link Random} instance, the * global execution paths can always be repeated from the same master seed. The * question is: how do we know what master seed was used? There are at least two * ways to find out. * *

The master seed is always available from * {@link RandomizedContext#getRunnerSeedAsString()} so one can simply print it to the * console. The current context's {@link Randomness} itself can be printed to the * console. In two methods in this class {@link #printMasterContext()} and {@link #printContext()} * we print the master seed and current context's {@link Randomness}, note how the static * context's {@link Randomness} is identical with the runner's but the test context * is a derived value. *

 * # Static context ({@literal @}BeforeClass)
 * AF567B2B9F8A8F1C
 * [Randomness, seed=[AF567B2B9F8A8F1C]]
 * # Test context ({@literal @}Test)
 * AF567B2B9F8A8F1C
 * [Randomness, seed=[EE581D5EC61D6BCF]]
 * 
* In {@link Test006RepeatingTests} we will see how this derived * seed is used with {@link Repeat} annotation. * *

Normally we will not be interested in a random seed if a test case passes. But if a test * case fails we will want to know the seed to be able to repeat the test. {@link RandomizedRunner} * augments the stack trace of all exceptions that cross the context boundary (this includes * assertion errors, assumption failures and any other exceptions). In method {@link #failure()} * we demonstrate this by failing on a constant condition. If you run this test suite, you'll note * the stack trace of the failing method to be something like this: *

 * java.lang.AssertionError
 *   at __randomizedtesting.SeedInfo.seed([AF567B2B9F8A8F1C:44E2D1A039274F2A]:0)
 *   at org.junit.Assert.fail(Assert.java:92)
 * 
* * The first line of the stack trace is a synthetic (non-existing) class with "source file" * entry containing all contexts' seeds on the stack (from master to the current test method). * In this case, you can see the master context first (AF567B2B9F8A8F1C), followed * by the test's context (44E2D1A039274F2A). The entire class has a fixed master seed * so that the result will always be the same here: *
 * {@literal @}{@link Seed}("AF567B2B9F8A8F1C")
 * public class Test005RecoveringRandomSeed extends RandomizedTest { // ...
 * 
*/ @Seed("AF567B2B9F8A8F1C") public class Test005RecoveringRandomSeed extends RandomizedTest { @BeforeClass public static void printMasterContext() { System.out.println("# Static context (@BeforeClass)"); System.out.println(getContext().getRunnerSeedAsString()); System.out.println(RandomizedContext.current().getRandomness()); } @Test public void printContext() { System.out.println("# Test context (@Test)"); System.out.println(getContext().getRunnerSeedAsString()); System.out.println(RandomizedContext.current().getRandomness()); } @Test public void failure() { Assert.assertTrue(false); } } Test006RepeatingTests.java000066400000000000000000000041101235451432000415200ustar00rootroot00000000000000randomizedtesting-release-2.1.6/examples/maven/src/main/java/com/carrotsearch/examples/randomizedrunnerpackage com.carrotsearch.examples.randomizedrunner; import org.junit.*; import com.carrotsearch.randomizedtesting.*; import com.carrotsearch.randomizedtesting.annotations.Repeat; import com.carrotsearch.randomizedtesting.annotations.Seed; /** * In example {@link Test005RecoveringRandomSeed} we presented * {@link Randomness} contexts and how they are derived from a master seed. Once * you know a certain test case fails it is usually beneficial to immediately * check if it always fails on a given seed (which means there is a * deterministic failure scenario). A simple way to do so would be to re-run a * test case a few times. The same effect can be achieved by adding a * {@link Repeat} annotation with {@link Repeat#useConstantSeed()} set to * false attribute as shown in the method {@link #repeatFailure()} * below. *
 * {@literal @}{@link Repeat}(iterations = 5, useConstantSeed = true)
 * {@literal @}{@link Seed}("f00ddead")
 * {@literal @}{@link Test}
 * public void repeatFailure() { //...
 * 
* Note how the seed is fixed using {@link Seed} annotation (on the * method) rather than on the master. This ensures the method's context is * pinned to that value, but the master is still random. If you have * {@link BeforeClass} hooks that depend on randomness you should use * suite-level {@link Seed} annotation and pin the master seed instead. * *

You can also set {@link Repeat#useConstantSeed()} to false and * then every iteration of the test method will have a pseudo-random context derived * from the first one (pinned or not). This can be useful to tell how frequently * a given test case fails for a random seed. For {@link #halfAndHalf()} method * about 50% of iterations will fail. */ public class Test006RepeatingTests extends RandomizedTest { @Repeat(iterations = 5, useConstantSeed = true) @Seed("f00ddead") @Test public void repeatFailure() { assertTrue(randomBoolean()); } @Repeat(iterations = 10, useConstantSeed = false) @Test public void halfAndHalf() { assertTrue(randomBoolean()); } } Test007ParameterizedTests.java000066400000000000000000000053051235451432000424060ustar00rootroot00000000000000randomizedtesting-release-2.1.6/examples/maven/src/main/java/com/carrotsearch/examples/randomizedrunnerpackage com.carrotsearch.examples.randomizedrunner; import java.util.Arrays; import org.junit.Test; import org.junit.runners.Parameterized; import com.carrotsearch.randomizedtesting.RandomizedRunner; import com.carrotsearch.randomizedtesting.RandomizedTest; import com.carrotsearch.randomizedtesting.annotations.*; /** * Parameterized tests are tricky. JUnit's {@link Parameterized} runner is * notoriously bad at giving human-readable test case names (there are several * patch proposal on github but not applied to the trunk at the time of writing * this). * *

{@link RandomizedRunner} has built-in support for parameters using a pair * of static-parameters provider method (factory) and a matching constructor. * The static method has to be public and annotated with {@link ParametersFactory}, * as in {@link #parameters()} method below. Note the funky-looking $ * and $$ method which are static varargs collector methods to avoid * explicit array constructors. *

 * {@literal @}{@link ParametersFactory}
 * public static Iterable parameters() {
 *   return Arrays.asList($$(
 *     $(1, "abc"), 
 *     $(2, "def")));
 * }
 * 
* *

The matching class constructor must declare type-assignable parameters. Because method * arguments are not part of the Java reflection, they can be explicitly annotated using * {@link Name} annotation to provide sensible names. * The {@link #Test007ParameterizedTests(int, String)} * constructor shows an example of how this looks. * *

If there is more than one set of parameters, method names will be postfixed with * a list of parameters and their values. An additional #num identifier will * be added to make tests unique. * *

{@link ParametersFactory} can be combined with other annotations such as * {@link Repeat} or {@link Seeds} as shown in {@link #paramsWithRepeatAndSeeds()}. */ public class Test007ParameterizedTests extends RandomizedTest { private int value; private String string; public Test007ParameterizedTests( @Name("value") int value, @Name("string") String string) { this.value = value; this.string = string; } @Test public void simpleArgumentsConsumer() { System.out.println(value + " " + string + " " + getContext().getRandomness()); } @Seeds({@Seed("deadbeef"), @Seed("cafebabe")}) @Test @Repeat(iterations = 2, useConstantSeed = true) public void paramsWithRepeatAndSeeds() { System.out.println(value + " " + string + " " + getContext().getRandomness()); } @ParametersFactory public static Iterable parameters() { return Arrays.asList($$( $(1, "abc"), $(2, "def"))); } } Test008Timeouts.java000066400000000000000000000044351235451432000404040ustar00rootroot00000000000000randomizedtesting-release-2.1.6/examples/maven/src/main/java/com/carrotsearch/examples/randomizedrunnerpackage com.carrotsearch.examples.randomizedrunner; import org.junit.Test; import com.carrotsearch.randomizedtesting.RandomizedRunner; import com.carrotsearch.randomizedtesting.RandomizedTest; import com.carrotsearch.randomizedtesting.annotations.Timeout; /** * {@link RandomizedRunner} has built-in support for enforcing test timeouts. If * a given test fails to execute in the given deadline, its thread will be * forcibly terminated (details below) and the test case will end in a failure. * *

* A timeout can be specified in two ways. First, the standard JUnit's * {@link Test#timeout()} attribute can be used (see * {@link #standardAnnotation()}). Alternatively, a more specific @link Timeout} * annotation is also provided if one needs to be explicit. * *

* The termination of a test thread is done in several steps ranking from subtle * to brute-force: *

* *

* The information about attempts to interrupt the thread are logged to the * Java's logging system along with the information about stack traces where the * thread resided when interrupts were sent to it. This is typically useful in * diagnosing what the thread was doing and why it couldn't be terminated. Keeping * Java logging system enabled is thus strongly encouraged. * * @see RandomizedRunner#SYSPROP_KILLATTEMPTS * @see RandomizedRunner#SYSPROP_KILLWAIT */ @SuppressWarnings("javadoc") public class Test008Timeouts extends RandomizedTest { @Test(timeout = 500) public void standardAnnotation() { sleep(10000); } @Test @Timeout(millis = 500) public void timeoutAnnotation() { sleep(10000); } } Test009ThreadLeaks.java000066400000000000000000000037371235451432000407670ustar00rootroot00000000000000randomizedtesting-release-2.1.6/examples/maven/src/main/java/com/carrotsearch/examples/randomizedrunnerpackage com.carrotsearch.examples.randomizedrunner; import java.util.concurrent.*; import org.junit.*; import com.carrotsearch.randomizedtesting.RandomizedRunner; import com.carrotsearch.randomizedtesting.RandomizedTest; /** * Leaked background threads can crash tests randomly even if all seeds are * known and predictable. They can also affect other test cases and so we should * not allow any threads to "leak outside" of their scope (a single test case or * a single suite if the thread is started in {@link BeforeClass} or * {@link AfterClass} hooks). * *

* {@link RandomizedRunner} has built-in support for detecting threads that * escaped their current {@link ThreadGroup}'s boundary. Such threads are killed * and make the test (or suite) fail with appropriate exception. * {@link #leftOverThread()} method below shows a simple scenario in which a * test leaks outside its test boundary. A correct code that calls {@link Thread#join()} * is shown in {@link #noLeakHere()}. * *

* More concepts concerning leaking threads and some workarounds for typical * problems with them is shown in {@link Test010Lingering}. */ public class Test009ThreadLeaks extends RandomizedTest { @Test public void leftOverThread() throws Exception { final CountDownLatch go = new CountDownLatch(1); Thread t = new Thread() { public void run() { try { go.countDown(); Thread.sleep(1000); } catch (InterruptedException e) {/* ignore */} } }; // Start and wait for it to really start. t.start(); go.await(); } @Test public void noLeakHere() throws Exception { final CountDownLatch go = new CountDownLatch(1); Thread t = new Thread() { public void run() { try { go.countDown(); Thread.sleep(1000); } catch (InterruptedException e) {/* ignore */} } }; // Start and wait for it to really start. t.start(); go.await(); t.join(); } } Test010Lingering.java000066400000000000000000000062671235451432000405070ustar00rootroot00000000000000randomizedtesting-release-2.1.6/examples/maven/src/main/java/com/carrotsearch/examples/randomizedrunnerpackage com.carrotsearch.examples.randomizedrunner; import java.util.concurrent.*; import junit.framework.Assert; import org.junit.Test; import com.carrotsearch.randomizedtesting.RandomizedRunner; import com.carrotsearch.randomizedtesting.RandomizedTest; import com.carrotsearch.randomizedtesting.annotations.Repeat; import com.carrotsearch.randomizedtesting.annotations.ThreadLeakAction; import com.carrotsearch.randomizedtesting.annotations.ThreadLeakLingering; import com.carrotsearch.randomizedtesting.annotations.ThreadLeakScope; import com.carrotsearch.randomizedtesting.annotations.ThreadLeakZombies; /** * In many cases the creation of background threads lies beyond our control (and * their direct termination or even awaiting for their termination) is not * possible. A good example is the {@link Executors} framework where background * {@link ThreadFactory} is not published if not given explicitly. * To handle such situations {@link RandomizedRunner} needs to know if it should * await background thread to complete (and for how long) or if it should allow * them to "leak" safely and not complain. All this can be declared with a set * of annotations starting with ThreadLeak* prefix. * *

We can use {@link ThreadLeakLingering} annotation instead of explicitly using * {@link Thread#join()} sometimes. For example, {@link Test009ThreadLeaks#leftOverThread()} * can be rewritten as shown in {@link #lingerForLeftOverThread()}. * *

The same annotation can be used to wait for background threads * which we don't have any control on, but we know they will eventually terminate. * For example, a terminated {@link Executor} does not wait (join) with its slave * threads so lingering here is required. This is shown in method {@link #executorLeak()}. This * method will fail (from time to time, it isn't guaranteed) if no lingering time is given. * *

There are other annotations for advanced control of thread leaks and their outcomes, check out * the javadocs in the links below. * * @see ThreadLeakScope * @see ThreadLeakLingering * @see ThreadLeakAction * @see ThreadLeakZombies */ public class Test010Lingering extends RandomizedTest { @Test @ThreadLeakLingering(linger = 2000) public void lingerForLeftOverThread() throws Exception { final CountDownLatch go = new CountDownLatch(1); Thread t = new Thread() { public void run() { try { go.countDown(); Thread.sleep(1000); } catch (InterruptedException e) {/* ignore */} } }; // Start and wait for it to really start. t.start(); go.await(); } // @ThreadLeaks(linger = 1000) // Enable me to make it pass all the time. @Test @Repeat(iterations = 10) public void executorLeak() throws Exception { int numThreads = 50; final ExecutorService executor = Executors.newFixedThreadPool(numThreads); for (int i = 0; i < 2 * numThreads; i++) { executor.submit(new Runnable() { public void run() { sleep(10); } }); } executor.shutdown(); executor.awaitTermination(1, TimeUnit.SECONDS); Assert.assertTrue(executor.isShutdown()); Assert.assertTrue(executor.isTerminated()); } } Test011NightlyTests.java000066400000000000000000000043121235451432000412200ustar00rootroot00000000000000randomizedtesting-release-2.1.6/examples/maven/src/main/java/com/carrotsearch/examples/randomizedrunnerpackage com.carrotsearch.examples.randomizedrunner; import org.junit.Assume; import org.junit.Test; import com.carrotsearch.randomizedtesting.*; import com.carrotsearch.randomizedtesting.annotations.Nightly; /** * Running tests on a developer machine is often a pain, in particular when * certain tests are long and repetitive. If you have a dedicated continuous * integration environment like Jenkins or * Attlasian Bamboo then it * is nice to be able to "stress" your tests a bit more during nightly or server * runs compared to normal developer runs. * *

{@link RandomizedRunner} has a notion of a {@link Nightly} test and a few methods * for "scaling" the execution depending if is in nightly mode or not. In the simplest * case (see {@link #nightlyOnly()} a test case is run in nightly mode and ignored in * normal runs. This can be done by annotating a test case or suite using {@link Nightly} * or by assuming nightly mode (using the result of {@link RandomizedContext#isNightly()} * as the condition). There is a difference between these two methods and it is left as an * exercise for the reader to discover what this difference is. * *

For tests whose runtime depends on the amount of input data or other varying complexity, * one can use {@link RandomizedTest#scaledRandomIntBetween(int, int)} method or the current * {@link RandomizedTest#multiplier()}. These methods adjust to the nightly mode picking * larger values than in daily mode (see javadocs for details). */ public class Test011NightlyTests extends RandomizedTest { @Nightly @Test public void nightlyOnly() throws Exception { // Do nothing, but pretend we're long and slow. } @Test public void nightlyOnlyWithAssume() throws Exception { Assume.assumeTrue(isNightly()); // Do nothing, but pretend we're long and slow. } @Test public void scaling() throws Exception { System.out.println("Mode: " + (isNightly() ? "nightly" : "daily")); System.out.println("Multiplier: " + multiplier()); for (int i = 0; i < 10; i++) { System.out.println("random scaled int = " + scaledRandomIntBetween(0, 100)); } } } Test012TestGroups.java000066400000000000000000000064321235451432000407040ustar00rootroot00000000000000randomizedtesting-release-2.1.6/examples/maven/src/main/java/com/carrotsearch/examples/randomizedrunnerpackage com.carrotsearch.examples.randomizedrunner; import java.lang.annotation.*; import org.junit.Test; import com.carrotsearch.randomizedtesting.RandomizedRunner; import com.carrotsearch.randomizedtesting.RandomizedTest; import com.carrotsearch.randomizedtesting.annotations.Nightly; import com.carrotsearch.randomizedtesting.annotations.TestGroup; /** * We introduced the notion of {@link Nightly} tests in * {@link Test011NightlyTests}. Similar to this idea, the user can introduce any * number of custom test groups which can be arbitrarily enabled or disabled. In * fact, {@link Nightly} is also defined as such a {@link TestGroup}. * *

* A custom test group is an annotation itself annotated with a * {@link TestGroup}. For example, let's say we want a test group that marks all * tests that require a physical display. An annotation for this is shown in * {@link Test012TestGroups.RequiresDisplay}. It has no additional attributes. * What makes it a test group is a meta-annotation: * *

 * {@literal @}{@link TestGroup}(name = "requiresdisplay", enabled = false, sysProperty = "display")
 * 
* * which states that the group's name is "requiresdisplay" and that the group is * initially disabled unless a system property "display" is set to a boolean * value "false", "off" or "disabled". * *

* {@link Nightly} is defined in a very similar way. Note that test groups are * real annotations so they are recognizable by IDEs, can be searched, * manipulated etc. * *

* Another feature of using {@link RandomizedRunner} with groups is the ability to specify * complex group-based filters specified via tests.filter system property. * These filters are boolean conditions, with optional parentheses. For example: *

* * Important! Note that using filtering expression has precedence over the default state of a group * and its corresponding system property. This is intentional so that filtering expressions can be used * independently of each group's default state. Should the default state be taken into account one * can use a special keyword default, as in: * */ public class Test012TestGroups extends RandomizedTest { @TestGroup(name = "requiresdisplay", enabled = false, sysProperty = "display") @Retention(RetentionPolicy.RUNTIME) @Target({ElementType.METHOD}) public static @interface RequiresDisplay {} @Test @RequiresDisplay public void usesDisplay() { System.out.println("Running on windows."); } } Test014Listeners.java000066400000000000000000000020731235451432000405340ustar00rootroot00000000000000randomizedtesting-release-2.1.6/examples/maven/src/main/java/com/carrotsearch/examples/randomizedrunnerpackage com.carrotsearch.examples.randomizedrunner; import junit.framework.Assert; import org.junit.Test; import org.junit.runner.notification.RunListener; import com.carrotsearch.randomizedtesting.RandomizedRunner; import com.carrotsearch.randomizedtesting.RandomizedTest; import com.carrotsearch.randomizedtesting.annotations.Listeners; import com.carrotsearch.randomizedtesting.listeners.ReproduceInfoPrinter; /** * {@link RandomizedRunner} respects an on-suite class {@link Listeners} * annotation and instantiates classes that implement {@link RunListener}. This * allows custom listener hooks on the suite. * *

* We honestly don't know where this would be useful. For now there are just a * few listeners, among them {@link ReproduceInfoPrinter} which dumps failure * information along with a preformatted JVM-options string to reproduce the * given test case (includes seed and filters). */ @Listeners({ReproduceInfoPrinter.class}) public class Test014Listeners extends RandomizedTest { @Test public void failure() { Assert.assertTrue(false); } } Test015CustomMethodProviders.java000066400000000000000000000037421235451432000431020ustar00rootroot00000000000000randomizedtesting-release-2.1.6/examples/maven/src/main/java/com/carrotsearch/examples/randomizedrunnerpackage com.carrotsearch.examples.randomizedrunner; import java.lang.reflect.Method; import java.util.ArrayList; import java.util.Collection; import java.util.List; import com.carrotsearch.randomizedtesting.ClassModel; import com.carrotsearch.randomizedtesting.RandomizedRunner; import com.carrotsearch.randomizedtesting.RandomizedTest; import com.carrotsearch.randomizedtesting.TestMethodProvider; import com.carrotsearch.randomizedtesting.annotations.Repeat; import com.carrotsearch.randomizedtesting.annotations.TestMethodProviders; /** * Because many people are nearly religious about how test methods * should be annotated or structured {@link RandomizedRunner} can use * a custom method selector for designating test methods. * *

This class contains a method selector that returns all methods * that end with a substring Test. */ public class Test015CustomMethodProviders { public static class MethodEndsWithTest implements TestMethodProvider { @Override public Collection getTestMethods(Class clz, ClassModel suiteClassModel) { /* * We pick all methods with a "Test" suffix. We also skip methods belonging to * RandomizedTest (there is a private method ending in Test there and this wouldn't * validate). Additional validation is performed in the runner (public, non-static, * no-args methods only allowed). */ List result = new ArrayList(); for (Method m : suiteClassModel.getMethods().keySet()) { if (m.getName().endsWith("Test") && !m.getDeclaringClass().equals(RandomizedTest.class)) { result.add(m); } } return result; } } @TestMethodProviders({ MethodEndsWithTest.class }) public static class TestClass extends RandomizedTest { public void myFirstTest() { System.out.println("First test."); } @Repeat(iterations = 5) public void mySecondTest() { System.out.println("Second test."); } } } 000077500000000000000000000000001235451432000363305ustar00rootroot00000000000000randomizedtesting-release-2.1.6/examples/maven/src/main/java/com/carrotsearch/examples/randomizedrunner/reportsTest001AllStatuses.java000066400000000000000000000007561235451432000425300ustar00rootroot00000000000000randomizedtesting-release-2.1.6/examples/maven/src/main/java/com/carrotsearch/examples/randomizedrunner/reportspackage com.carrotsearch.examples.randomizedrunner.reports; import junit.framework.Assert; import org.junit.Assume; import org.junit.Ignore; import org.junit.Test; public class Test001AllStatuses { @Test public void passed() {} @Test @Ignore public void ignored() {} @Test public void ignored_assumption() { Assume.assumeTrue(false); } @Test public void failure() { Assert.fail(); } @Test public void error() { throw new RuntimeException(); } } Test002SuiteFailure.java000066400000000000000000000007071235451432000426620ustar00rootroot00000000000000randomizedtesting-release-2.1.6/examples/maven/src/main/java/com/carrotsearch/examples/randomizedrunner/reportspackage com.carrotsearch.examples.randomizedrunner.reports; import org.junit.AfterClass; import org.junit.BeforeClass; import org.junit.Test; /** * Suite-level failures. */ public class Test002SuiteFailure { @BeforeClass public static void beforeClass() { throw new RuntimeException("beforeClass"); } @Test public void testCase() {} @AfterClass public static void afterClass() { throw new RuntimeException("afterClass"); } } Test003MultipleFailures.java000066400000000000000000000023671235451432000435540ustar00rootroot00000000000000randomizedtesting-release-2.1.6/examples/maven/src/main/java/com/carrotsearch/examples/randomizedrunner/reportspackage com.carrotsearch.examples.randomizedrunner.reports; import java.util.Arrays; import org.junit.After; import org.junit.AfterClass; import org.junit.Rule; import org.junit.Test; import org.junit.rules.TestRule; import org.junit.runner.Description; import org.junit.runners.model.MultipleFailureException; import org.junit.runners.model.Statement; /** * Multiple failures from a single test case (followed by a suite-failure). */ public class Test003MultipleFailures { @Rule public TestRule rule = new TestRule() { @Override public Statement apply(final Statement base, Description description) { return new Statement() { @Override public void evaluate() throws Throwable { try { base.evaluate(); } catch (Throwable t) { throw new MultipleFailureException(Arrays.asList( t, new Exception("a"), new Exception("b"))); } } }; } }; @Test public void testCase() { throw new RuntimeException("testCase"); } @After public void after() { throw new RuntimeException("after"); } @AfterClass public static void afterClass() { throw new RuntimeException("afterClass"); } } Test004SuiteOfNested.java000066400000000000000000000011201235451432000427720ustar00rootroot00000000000000randomizedtesting-release-2.1.6/examples/maven/src/main/java/com/carrotsearch/examples/randomizedrunner/reportspackage com.carrotsearch.examples.randomizedrunner.reports; import org.junit.runner.RunWith; import org.junit.runners.Suite; import org.junit.runners.Suite.SuiteClasses; /** * A suite of nested test classes. */ @RunWith(Suite.class) @SuiteClasses({ Test004SuiteOfNested.Subclass1.class, Test004SuiteOfNested.Subclass2.class, Test004SuiteOfNested.Subclass3.class }) public class Test004SuiteOfNested { public static class Subclass1 extends Test001AllStatuses { } public static class Subclass2 extends Subclass1 { } public static class Subclass3 extends Subclass1 { } } Test005WithOutput.java000066400000000000000000000016751235451432000424250ustar00rootroot00000000000000randomizedtesting-release-2.1.6/examples/maven/src/main/java/com/carrotsearch/examples/randomizedrunner/reportspackage com.carrotsearch.examples.randomizedrunner.reports; import org.junit.Test; /** * A suite of nested test classes. */ public class Test005WithOutput { @Test public void stdout() { System.out.print("stdout-noeol"); } @Test public void stdout_eol() { System.out.print("stdout-witheol\n"); } @Test public void stderr() { System.err.print("stderr-noeol"); } @Test public void stderr_eol() { System.err.print("stderr-witheol\n"); } @Test public void stderr_stdout_interwoven() { System.out.print("stdout-begin-"); System.out.flush(); System.err.print("stderr-begin-"); System.err.flush(); System.out.print("stdout-end"); System.out.flush(); System.err.print("stderr-end"); System.err.flush(); } @Test public void longline() { for (int i = 0; i < 1000; i++) { System.out.print((i % 10) + '0'); } System.out.println("... and done."); } } Test006BeforeClassFailure.java000066400000000000000000000004741235451432000437660ustar00rootroot00000000000000randomizedtesting-release-2.1.6/examples/maven/src/main/java/com/carrotsearch/examples/randomizedrunner/reportspackage com.carrotsearch.examples.randomizedrunner.reports; import junit.framework.Assert; import org.junit.BeforeClass; import org.junit.Test; /** */ public class Test006BeforeClassFailure { @BeforeClass public static void failOnMe() { Assert.assertTrue(false); } @Test public void noop() { } } Test006BeforeClassFailureRR.java000066400000000000000000000006751235451432000442350ustar00rootroot00000000000000randomizedtesting-release-2.1.6/examples/maven/src/main/java/com/carrotsearch/examples/randomizedrunner/reportspackage com.carrotsearch.examples.randomizedrunner.reports; import junit.framework.Assert; import org.junit.BeforeClass; import org.junit.Test; import org.junit.runner.RunWith; import com.carrotsearch.randomizedtesting.RandomizedRunner; /** */ @RunWith(RandomizedRunner.class) public class Test006BeforeClassFailureRR { @BeforeClass public static void failOnMe() { Assert.assertTrue(false); } @Test public void noop() { } } Test007BeforeClassError.java000066400000000000000000000004371235451432000434700ustar00rootroot00000000000000randomizedtesting-release-2.1.6/examples/maven/src/main/java/com/carrotsearch/examples/randomizedrunner/reportspackage com.carrotsearch.examples.randomizedrunner.reports; import org.junit.BeforeClass; import org.junit.Test; /** */ public class Test007BeforeClassError { @BeforeClass public static void errorOnMe() { throw new RuntimeException(); } @Test public void noop() { } } Test007BeforeClassErrorRR.java000066400000000000000000000006401235451432000437300ustar00rootroot00000000000000randomizedtesting-release-2.1.6/examples/maven/src/main/java/com/carrotsearch/examples/randomizedrunner/reportspackage com.carrotsearch.examples.randomizedrunner.reports; import org.junit.BeforeClass; import org.junit.Test; import org.junit.runner.RunWith; import com.carrotsearch.randomizedtesting.RandomizedRunner; /** */ @RunWith(RandomizedRunner.class) public class Test007BeforeClassErrorRR { @BeforeClass public static void errorOnMe() { throw new RuntimeException(); } @Test public void noop() { } } Test008BeforeClassAssumption.java000066400000000000000000000003761235451432000445440ustar00rootroot00000000000000randomizedtesting-release-2.1.6/examples/maven/src/main/java/com/carrotsearch/examples/randomizedrunner/reportspackage com.carrotsearch.examples.randomizedrunner.reports; import org.junit.*; /** */ public class Test008BeforeClassAssumption { @BeforeClass public static void assumeMe() { Assume.assumeTrue(false); } @Test public void noop() { } } Test008BeforeClassAssumptionRR.java000066400000000000000000000005771235451432000450130ustar00rootroot00000000000000randomizedtesting-release-2.1.6/examples/maven/src/main/java/com/carrotsearch/examples/randomizedrunner/reportspackage com.carrotsearch.examples.randomizedrunner.reports; import org.junit.*; import org.junit.runner.RunWith; import com.carrotsearch.randomizedtesting.RandomizedRunner; /** */ @RunWith(RandomizedRunner.class) public class Test008BeforeClassAssumptionRR { @BeforeClass public static void assumeMe() { Assume.assumeTrue(false); } @Test public void noop() { } } randomizedtesting-release-2.1.6/junit4-ant/000077500000000000000000000000001235451432000206645ustar00rootroot00000000000000randomizedtesting-release-2.1.6/junit4-ant/lib/000077500000000000000000000000001235451432000214325ustar00rootroot00000000000000randomizedtesting-release-2.1.6/junit4-ant/pom.xml000066400000000000000000000255541235451432000222140ustar00rootroot00000000000000 4.0.0 com.carrotsearch.randomizedtesting randomizedtesting-parent 2.1.6 ../pom.xml junit4-ant org.apache.ant ant provided org.apache.ant ant-junit provided junit junit jar provided com.google.guava guava provided jsr305 com.google.code.findbugs org.ow2.asm asm provided commons-io commons-io provided com.google.code.gson gson provided org.simpleframework simple-xml provided com.carrotsearch.randomizedtesting randomizedtesting-runner ${project.version} provided org.apache.maven.plugins maven-surefire-plugin ${project.build.directory}/test-classes **/tests/** **/it/** surefire-it integration-test test **/it/Test*.java **/tests/** ${project.build.directory}/dontinclude com.carrotsearch.randomizedtesting:randomizedtesting-runner com.google.code.gson:gson com.google.guava:guava org.simpleframework:simple-xml commons-io:commons-io org.eclipse.m2e lifecycle-mapping 1.0.0 org.apache.maven.plugins maven-dependency-plugin [1.0.0,) copy-dependencies org.apache.maven.plugins maven-javadoc-plugin ${basedir}/src/main/java/com/carrotsearch/ant/tasks/junit4/package.html JUnit4 ANT task com.carrotsearch.ant.tasks.junit4* Listeners and report writers com.carrotsearch.ant.tasks.junit4.listeners* Load balancers com.carrotsearch.ant.tasks.junit4.balancers* Events and aggregated events for reports com.carrotsearch.ant.tasks.junit4.events*

${project.name} v${project.version}
API Documentation]]>
com.carrotsearch.ant.tasks.junit4.slave org.apache.maven.plugins maven-dependency-plugin copy-dependencies package copy-dependencies com.carrotsearch.randomizedtesting,junit,org.ow2.asm org.codehaus.mojo exec-maven-plugin 1.2.1 package java proguard.DetectRtJar test ${project.build.directory}/rt.jar.pro org.apache.maven.plugins maven-jar-plugin true com.pyx4me proguard-maven-plugin 2.0.4 package proguard com.google.guava guava !com/google/common/eventbus/SynchronizedEventHandler.class org.ow2.asm asm commons-io commons-io org.simpleframework simple-xml com.google.code.gson gson com.carrotsearch.randomizedtesting randomizedtesting-runner true true false true ${project.build.directory} ${basedir}/src/proguard/rules.pro net.sf.proguard proguard 4.6-customized system ${project.basedir}/lib/proguard.jar src/main/resources **/*.jsonp **/ideas.txt randomizedtesting-release-2.1.6/junit4-ant/src/000077500000000000000000000000001235451432000214535ustar00rootroot00000000000000randomizedtesting-release-2.1.6/junit4-ant/src/main/000077500000000000000000000000001235451432000223775ustar00rootroot00000000000000randomizedtesting-release-2.1.6/junit4-ant/src/main/java/000077500000000000000000000000001235451432000233205ustar00rootroot00000000000000randomizedtesting-release-2.1.6/junit4-ant/src/main/java/com/000077500000000000000000000000001235451432000240765ustar00rootroot00000000000000randomizedtesting-release-2.1.6/junit4-ant/src/main/java/com/carrotsearch/000077500000000000000000000000001235451432000265565ustar00rootroot00000000000000randomizedtesting-release-2.1.6/junit4-ant/src/main/java/com/carrotsearch/ant/000077500000000000000000000000001235451432000273405ustar00rootroot00000000000000randomizedtesting-release-2.1.6/junit4-ant/src/main/java/com/carrotsearch/ant/tasks/000077500000000000000000000000001235451432000304655ustar00rootroot00000000000000randomizedtesting-release-2.1.6/junit4-ant/src/main/java/com/carrotsearch/ant/tasks/junit4/000077500000000000000000000000001235451432000317025ustar00rootroot00000000000000BalancersList.java000066400000000000000000000006571235451432000352240ustar00rootroot00000000000000randomizedtesting-release-2.1.6/junit4-ant/src/main/java/com/carrotsearch/ant/tasks/junit4package com.carrotsearch.ant.tasks.junit4; import java.util.List; /** * A nested list of {@link SuiteBalancer}s. */ public class BalancersList { private List balancers; public BalancersList(List balancers) { this.balancers = balancers; } /** * Adds a balancer to the balancers list. */ public void addConfigured(SuiteBalancer balancer) { balancers.add(balancer); } } DecodeEventStream.java000066400000000000000000000026721235451432000360360ustar00rootroot00000000000000randomizedtesting-release-2.1.6/junit4-ant/src/main/java/com/carrotsearch/ant/tasks/junit4package com.carrotsearch.ant.tasks.junit4; import java.io.FileInputStream; import java.io.IOException; import java.io.InputStreamReader; import java.io.Reader; import com.carrotsearch.ant.tasks.junit4.events.EventType; import com.carrotsearch.ant.tasks.junit4.events.IStreamEvent; import com.carrotsearch.ant.tasks.junit4.events.json.JsonByteArrayAdapter; import com.google.common.base.Charsets; import com.google.gson.Gson; import com.google.gson.GsonBuilder; import com.google.gson.stream.JsonReader; /** * A simple utility to decode JSON event stream's APPEND_* chunks back into * a character stream. */ public class DecodeEventStream { public static void main(String[] args) throws IOException { Reader is = new InputStreamReader(new FileInputStream(args[0]), Charsets.UTF_8); JsonReader reader = new JsonReader(is); reader.setLenient(true); Gson gson = new GsonBuilder() .registerTypeAdapter(byte[].class, new JsonByteArrayAdapter()) .create(); while (true) { reader.beginArray(); EventType type = EventType.valueOf(reader.nextString()); IStreamEvent evt; switch (type) { case APPEND_STDERR: case APPEND_STDOUT: evt = (IStreamEvent) gson.fromJson(reader, type.eventClass); evt.copyTo(System.out); break; default: System.out.println("\n\n## " + type); reader.skipValue(); } reader.endArray(); } } } DiagnosticsListener.java000066400000000000000000000020021235451432000364350ustar00rootroot00000000000000randomizedtesting-release-2.1.6/junit4-ant/src/main/java/com/carrotsearch/ant/tasks/junit4package com.carrotsearch.ant.tasks.junit4; import org.apache.tools.ant.Project; import org.apache.tools.ant.Task; import com.carrotsearch.ant.tasks.junit4.events.BootstrapEvent; import com.carrotsearch.ant.tasks.junit4.events.IEvent; import com.carrotsearch.ant.tasks.junit4.events.QuitEvent; import com.google.common.eventbus.Subscribe; public class DiagnosticsListener { private final ForkedJvmInfo slave; private boolean quitReceived; private Task task; public DiagnosticsListener(ForkedJvmInfo slave, JUnit4 task) { this.task = task; this.slave = slave; } @Subscribe public void receiveAll(IEvent e) { task.log("Packet received, slave#" + slave.id + ">" + e.getType(), Project.MSG_DEBUG); } @Subscribe public void receiveBootstrap(BootstrapEvent e) { task.log("Default encoding: " + e.getDefaultCharsetName(), Project.MSG_VERBOSE); } @Subscribe public void receiveQuit(QuitEvent e) { quitReceived = true; } boolean quitReceived() { return quitReceived; } } DuplicateResources.java000066400000000000000000000030001235451432000362640ustar00rootroot00000000000000randomizedtesting-release-2.1.6/junit4-ant/src/main/java/com/carrotsearch/ant/tasks/junit4package com.carrotsearch.ant.tasks.junit4; import java.util.ArrayList; import java.util.Iterator; import java.util.List; import org.apache.tools.ant.types.DataType; import org.apache.tools.ant.types.Resource; import org.apache.tools.ant.types.ResourceCollection; import com.google.common.collect.Iterators; /** * Duplicate nested resources N times. Useful for running * suites multiple times with load balancing. */ @SuppressWarnings("rawtypes") public class DuplicateResources extends DataType implements ResourceCollection { private final List rcs = new ArrayList(); private int times; public void addConfigured(ResourceCollection rc) { this.rcs.add(rc); } /** * Set the number of times the input resources should be duplicated. */ public void setTimes(int times) { this.times = times; } @SuppressWarnings("unchecked") @Override public Iterator iterator() { List elements = new ArrayList(); for (ResourceCollection rc : rcs) { for (Iterator i = rc.iterator(); i.hasNext();) { final Object o = i.next(); for (int t = 0; t < times; t++) { elements.add(o); } } } return elements.iterator(); } @Override public int size() { return Iterators.size(iterator()); } @Override public boolean isFilesystemOnly() { for (Iterator i = iterator(); i.hasNext();) { if (!((Resource) i.next()).isFilesystemOnly()) { return false; } } return true; } } Duration.java000066400000000000000000000026011235451432000342520ustar00rootroot00000000000000randomizedtesting-release-2.1.6/junit4-ant/src/main/java/com/carrotsearch/ant/tasks/junit4package com.carrotsearch.ant.tasks.junit4; import java.util.Locale; public final class Duration { /** * Format a duration in milliseconds to a human string (in English). */ public static CharSequence toHumanDuration(long duration) { final long MILLIS_IN_A_SECOND = 1000; final long MILLIS_IN_A_MINUTE = MILLIS_IN_A_SECOND * 60; final long MILLIS_IN_AN_HOUR = MILLIS_IN_A_MINUTE * 60; final long MILLIS_IN_A_DAY = MILLIS_IN_AN_HOUR * 24; boolean longTime = (duration >= MILLIS_IN_A_SECOND * 10); StringBuilder str = new StringBuilder(); duration = emitOrSkip(duration, str, MILLIS_IN_A_DAY, " day", true); duration = emitOrSkip(duration, str, MILLIS_IN_AN_HOUR, " hour", true); duration = emitOrSkip(duration, str, MILLIS_IN_A_MINUTE, " minute", true); if (longTime) { duration = emitOrSkip(duration, str, MILLIS_IN_A_SECOND, " second", true); } else { str.append(String.format(Locale.ENGLISH, "%.2f sec.", (duration / 1000.0f))); } return str; } private static long emitOrSkip(long value, StringBuilder str, long unit, String unitName, boolean skipEmpty) { final long units = value / unit; if (units != 0 || !skipEmpty) { if (str.length() > 0) str.append(" "); str.append(units) .append(Pluralize.pluralize((int) units, unitName)); } value -= units * unit; return value; } } ForkedJvmInfo.java000066400000000000000000000065231235451432000351770ustar00rootroot00000000000000randomizedtesting-release-2.1.6/junit4-ant/src/main/java/com/carrotsearch/ant/tasks/junit4package com.carrotsearch.ant.tasks.junit4; import java.io.IOException; import java.io.Writer; import java.nio.charset.Charset; import java.util.ArrayList; import java.util.List; import java.util.Map; import org.apache.commons.io.output.WriterOutputStream; import com.carrotsearch.ant.tasks.junit4.events.BootstrapEvent; import com.carrotsearch.ant.tasks.junit4.events.IEvent; import com.carrotsearch.ant.tasks.junit4.events.IStreamEvent; /** * Static slave information. */ public final class ForkedJvmInfo { /** * Unique sequential slave identifier. */ public final int id; /** * The number of executed slaves, total. */ public final int slaves; /** * Bootstrap event. */ private BootstrapEvent bootstrapEvent; /** * Timestamps for diagnostics. */ long start, end; /** * Execute these test suites on this slave. */ ArrayList testSuites; /** * Complete slave command line invocation string. */ String slaveCommandLine; /** * Execution error if anything bad happened on the slave. */ Throwable executionError; /* */ public ForkedJvmInfo(int id, int slaves) { this.id = id; this.slaves = slaves; } /** * Return the {@link Charset} used to encode stream bytes from the slave. */ public Charset getCharset() { if (bootstrapEvent != null) { return Charset.forName(bootstrapEvent.getDefaultCharsetName()); } else { return Charset.defaultCharset(); } } /** * System properties on the slave. */ public Map getSystemProperties() { return bootstrapEvent.getSystemProperties(); } /** * PID string of the forked JVM. May not be available or may come in an unknown format * (Java 8 will have real PID support, supposedly). */ public String getPidString() { return bootstrapEvent.getPidString(); } /** * Command line string used to invoke the slave. */ public String getCommandLine() { return slaveCommandLine; } /** * JVM name (slave). */ public String getJvmName() { return getSystemProperties().get("java.vm.name") + ", " + getSystemProperties().get("java.vm.version"); } /** * Slave execution time. */ long getExecutionTime() { return end - start; } /** * Set the bootstrap event associated with this slave. */ void setBootstrapEvent(BootstrapEvent e) { this.bootstrapEvent = e; } /** * Filter through events looking for sysouts and syserrs and decode them * into a character streams. If both {@link Writer} arguments are the same object * the streams will be combined. */ public void decodeStreams(List events, Writer sysout, Writer syserr) throws IOException { int lineBuffer = 160; WriterOutputStream stdout = new WriterOutputStream(sysout, getCharset(), lineBuffer, true); WriterOutputStream stderr = new WriterOutputStream(syserr, getCharset(), lineBuffer, true); for (IEvent evt : events) { switch (evt.getType()) { case APPEND_STDOUT: if (sysout != null) { ((IStreamEvent) evt).copyTo(stdout); } break; case APPEND_STDERR: if (syserr != null) { ((IStreamEvent) evt).copyTo(stderr); } break; default: break; } } stdout.flush(); stderr.flush(); } } FormattingUtils.java000066400000000000000000000040101235451432000356140ustar00rootroot00000000000000randomizedtesting-release-2.1.6/junit4-ant/src/main/java/com/carrotsearch/ant/tasks/junit4package com.carrotsearch.ant.tasks.junit4; import java.text.SimpleDateFormat; import java.util.Date; import java.util.Locale; import org.junit.runner.Description; /** * Formatting utilities for consistency across code. */ public final class FormattingUtils { /* */ public static String padTo(int columns, String text, String ellipsis) { if (text.length() < columns) { return text; } text = ellipsis + text.substring(text.length() - (columns - ellipsis.length())); return text; } public static String formatTime(long timestamp) { return new SimpleDateFormat("yyyy-MM-dd'T'HH:mm:ss", Locale.ENGLISH).format(new Date(timestamp)); } public static String formatTimestamp(long ts) { return new SimpleDateFormat("HH:mm:ss.SSS", Locale.US).format(new Date(ts)); } public static String formatDurationInSeconds(long timeMillis) { final int precision; if (timeMillis >= 100 * 1000) { precision = 0; } else if (timeMillis >= 10 * 1000) { precision = 1; } else { precision = 2; } return String.format(Locale.ENGLISH, "%4." + precision + "fs", timeMillis / 1000.0); } public static String formatDescription(Description description) { return formatDescription(description, false); } public static String formatDescription(Description description, boolean fullNames) { StringBuilder buffer = new StringBuilder(); String className = description.getClassName(); if (className != null) { if (fullNames) { buffer.append(className); } else { String [] components = className.split("[\\.]"); className = components[components.length - 1]; buffer.append(className); } if (description.getMethodName() != null) { buffer.append(".").append(description.getMethodName()); } else { buffer.append(" (suite)"); } } else { if (description.getMethodName() != null) { buffer.append(description.getMethodName()); } } return buffer.toString(); } } JUnit4.java000066400000000000000000001711421235451432000336110ustar00rootroot00000000000000randomizedtesting-release-2.1.6/junit4-ant/src/main/java/com/carrotsearch/ant/tasks/junit4package com.carrotsearch.ant.tasks.junit4; import static com.carrotsearch.randomizedtesting.SysGlobals.CURRENT_PREFIX; import static com.carrotsearch.randomizedtesting.SysGlobals.SYSPROP_PREFIX; import static com.carrotsearch.randomizedtesting.SysGlobals.SYSPROP_RANDOM_SEED; import static com.carrotsearch.randomizedtesting.SysGlobals.SYSPROP_TESTCLASS; import static com.carrotsearch.randomizedtesting.SysGlobals.SYSPROP_TESTMETHOD; import java.io.BufferedInputStream; import java.io.BufferedOutputStream; import java.io.File; import java.io.FileOutputStream; import java.io.IOException; import java.io.InputStream; import java.io.OutputStream; import java.io.PrintWriter; import java.io.RandomAccessFile; import java.io.Serializable; import java.nio.charset.Charset; import java.text.SimpleDateFormat; import java.util.ArrayDeque; import java.util.ArrayList; import java.util.Arrays; import java.util.Collection; import java.util.Collections; import java.util.Date; import java.util.Deque; import java.util.EnumSet; import java.util.Iterator; import java.util.List; import java.util.Locale; import java.util.Map; import java.util.Properties; import java.util.Random; import java.util.Vector; import java.util.concurrent.Callable; import java.util.concurrent.ExecutionException; import java.util.concurrent.ExecutorService; import java.util.concurrent.Executors; import java.util.concurrent.Future; import java.util.concurrent.atomic.AtomicBoolean; import java.util.concurrent.atomic.AtomicReference; import java.util.regex.Pattern; import org.apache.commons.io.FileUtils; import org.apache.commons.io.output.TeeOutputStream; import org.apache.tools.ant.AntClassLoader; import org.apache.tools.ant.BuildException; import org.apache.tools.ant.Project; import org.apache.tools.ant.ProjectComponent; import org.apache.tools.ant.Task; import org.apache.tools.ant.taskdefs.Execute; import org.apache.tools.ant.types.Assertions; import org.apache.tools.ant.types.Commandline; import org.apache.tools.ant.types.CommandlineJava; import org.apache.tools.ant.types.Environment; import org.apache.tools.ant.types.Environment.Variable; import org.apache.tools.ant.types.FileSet; import org.apache.tools.ant.types.Path; import org.apache.tools.ant.types.PropertySet; import org.apache.tools.ant.types.Resource; import org.apache.tools.ant.types.ResourceCollection; import org.apache.tools.ant.types.resources.Resources; import org.apache.tools.ant.util.LoaderUtils; import org.junit.runner.Description; import org.objectweb.asm.AnnotationVisitor; import org.objectweb.asm.ClassReader; import org.objectweb.asm.ClassVisitor; import org.objectweb.asm.Opcodes; import org.objectweb.asm.Type; import com.carrotsearch.ant.tasks.junit4.SuiteBalancer.Assignment; import com.carrotsearch.ant.tasks.junit4.balancers.RoundRobinBalancer; import com.carrotsearch.ant.tasks.junit4.balancers.SuiteHint; import com.carrotsearch.ant.tasks.junit4.events.BootstrapEvent; import com.carrotsearch.ant.tasks.junit4.events.QuitEvent; import com.carrotsearch.ant.tasks.junit4.events.aggregated.AggregatedQuitEvent; import com.carrotsearch.ant.tasks.junit4.events.aggregated.AggregatedStartEvent; import com.carrotsearch.ant.tasks.junit4.events.aggregated.AggregatingListener; import com.carrotsearch.ant.tasks.junit4.events.aggregated.ChildBootstrap; import com.carrotsearch.ant.tasks.junit4.listeners.AggregatedEventListener; import com.carrotsearch.ant.tasks.junit4.listeners.TextReport; import com.carrotsearch.ant.tasks.junit4.slave.SlaveMain; import com.carrotsearch.ant.tasks.junit4.slave.SlaveMainSafe; import com.carrotsearch.randomizedtesting.ClassGlobFilter; import com.carrotsearch.randomizedtesting.FilterExpressionParser; import com.carrotsearch.randomizedtesting.MethodGlobFilter; import com.carrotsearch.randomizedtesting.RandomizedRunner; import com.carrotsearch.randomizedtesting.SeedUtils; import com.carrotsearch.randomizedtesting.SysGlobals; import com.carrotsearch.randomizedtesting.FilterExpressionParser.Node; import com.carrotsearch.randomizedtesting.generators.RandomPicks; import com.google.common.base.Charsets; import com.google.common.base.Function; import com.google.common.base.Joiner; import com.google.common.base.Strings; import com.google.common.base.Throwables; import com.google.common.collect.Collections2; import com.google.common.collect.HashMultiset; import com.google.common.collect.Lists; import com.google.common.collect.Maps; import com.google.common.collect.Multimap; import com.google.common.collect.Multimaps; import com.google.common.collect.Multiset; import com.google.common.collect.Ordering; import com.google.common.eventbus.EventBus; import com.google.common.eventbus.Subscribe; import com.google.common.io.CharStreams; import com.google.common.io.Closeables; import com.google.common.io.Closer; import com.google.common.io.FileWriteMode; import com.google.common.io.Files; import com.google.gson.Gson; /** * An ANT task to run JUnit4 tests. Differences (benefits?) compared to ANT's default JUnit task: *
    *
  • Built-in parallel test execution support (spawns multiple JVMs to avoid * test interactions).
  • *
  • Randomization of the order of test suites within a single JVM.
  • *
  • Aggregates and synchronizes test events from executors. All reports run on * the task's JVM (not on the test JVM).
  • *
  • Fully configurable reporting via listeners (console, ANT-compliant XML, JSON). * Report listeners use Google Guava's {@link EventBus} and receive full information * about tests' execution (including skipped, assumption-skipped tests, streamlined * output and error stream chunks, etc.).
  • *
  • JUnit 4.10+ is required both for the task and for the tests classpath. * Older versions will cause build failure.
  • *
  • Integration with {@link RandomizedRunner} (randomization seed is passed to * children JVMs).
  • *
*/ public class JUnit4 extends Task { /** * Welcome messages. */ private static String [] WELCOME_MESSAGES = { "hello!", // en "hi!", // en "g'day!", // en, australia "¡Hola!", // es "jolly good day!", // monty python "aloha!", // en, hawaii "cześć!", // pl "مرحبا!", // arabic (modern) "kaixo!", // basque "Привет!", // bulgarian, russian "你好!", // cn, traditional "ahoj!", // czech "salut!", // french "hallo!", // german "שלו×!", // hebrew "नमसà¥à¤¤à¥‡!", // hindi "áŠáƒ!", // inuktitut "ciao!", // italian "今日ã¯!", // japanese "olá!", // portuguese // add more if your country/ place is not on the list ;) }; /** Name of the antlib resource inside JUnit4 JAR. */ public static final String ANTLIB_RESOURCE_NAME = "com/carrotsearch/junit4/antlib.xml"; /** @see #setParallelism(String) */ public static final Object PARALLELISM_AUTO = "auto"; /** @see #setParallelism(String) */ public static final String PARALLELISM_MAX = "max"; /** Default value of {@link #setShuffleOnSlave}. */ public static final boolean DEFAULT_SHUFFLE_ON_SLAVE = true; /** Default value of {@link #setParallelism}. */ public static final String DEFAULT_PARALLELISM = "1"; /** Default value of {@link #setPrintSummary}. */ public static final boolean DEFAULT_PRINT_SUMMARY = true; /** Default value of {@link #setHaltOnFailure}. */ public static final boolean DEFAULT_HALT_ON_FAILURE = true; /** Default value of {@link #setIsolateWorkingDirectories(boolean)}. */ public static final boolean DEFAULT_ISOLATE_WORKING_DIRECTORIES = true; /** Default value of {@link #setDynamicAssignmentRatio(float)} */ public static final float DEFAULT_DYNAMIC_ASSIGNMENT_RATIO = .25f; /** Default value of {@link #setSysouts}. */ public static final boolean DEFAULT_SYSOUTS = false; /** Default value of {@link #setDebugStream}. */ public static final boolean DEFAULT_DEBUGSTREAM = false; /** Default value of {@link #setUniqueSuiteNames(boolean)} */ public static final boolean DEFAULT_UNIQUE_SUITE_NAME = true; /** System property passed to forked VMs: current working directory (absolute). */ private static final String CHILDVM_SYSPROP_CWD = "junit4.childvm.cwd"; /** What to do on JVM output? */ public static enum JvmOutputAction { PIPE, IGNORE, FAIL, WARN } /** What to do when there were no executed tests (all ignored or none at all?). */ public static enum NoTestsAction { IGNORE, FAIL, WARN } /** * @see #setJvmOutputAction(String) */ public EnumSet jvmOutputAction = EnumSet.of( JvmOutputAction.PIPE, JvmOutputAction.WARN); /** * @see #setSysouts */ private boolean sysouts = DEFAULT_SYSOUTS; /** * @see #setDebugStream */ private boolean debugStream = DEFAULT_DEBUGSTREAM; /** * Slave VM command line. */ private CommandlineJava slaveCommand = new CommandlineJava(); /** * Set new environment for the forked process? */ private boolean newEnvironment; /** * @see #setUniqueSuiteNames */ private boolean uniqueSuiteNames = DEFAULT_UNIQUE_SUITE_NAME; /** * Environment variables to use in the forked JVM. */ private Environment env = new Environment(); /** * Directory to invoke slave VM in. */ private File dir; /** * Test names. */ private final Resources resources; /** * Stop the build process if there were errors? */ private boolean haltOnFailure = DEFAULT_HALT_ON_FAILURE; /** * Print summary of all tests at the end. */ private boolean printSummary = DEFAULT_PRINT_SUMMARY; /** * Property to set if there were test failures or errors. */ private String failureProperty; /** * A folder to store temporary files in. Defaults to {@link #dir} or * the project's basedir. */ private File tempDir; /** * Listeners listening on the event bus. */ private List listeners = Lists.newArrayList(); /** * Balancers scheduling tests for individual JVMs in parallel mode. */ private List balancers = Lists.newArrayList(); /** * Class loader used to resolve annotations and classes referenced from annotations * when {@link Description}s containing them are passed from slaves. */ private AntClassLoader testsClassLoader; /** * @see #setParallelism(String) */ private String parallelism = DEFAULT_PARALLELISM; /** * Set to true to leave temporary files (for diagnostics). */ private boolean leaveTemporary; /** * A list of temporary files to leave or remove if build passes. */ private List temporaryFiles = Collections.synchronizedList(Lists.newArrayList()); /** * @see #setSeed(String) */ private String random; /** * @see #setIsolateWorkingDirectories(boolean) */ private boolean isolateWorkingDirectories = DEFAULT_ISOLATE_WORKING_DIRECTORIES; /** * Multiple path resolution in {@link CommandlineJava#getCommandline()} is very slow * so we construct and canonicalize paths. */ private Path classpath; private Path bootclasspath; /** * @see #setDynamicAssignmentRatio(float) */ private float dynamicAssignmentRatio = DEFAULT_DYNAMIC_ASSIGNMENT_RATIO; /** * @see #setShuffleOnSlave(boolean) */ private boolean shuffleOnSlave = DEFAULT_SHUFFLE_ON_SLAVE; /** * @see #setHeartbeat */ private long heartbeat; /** * @see #setIfNoTests */ private NoTestsAction ifNoTests = NoTestsAction.IGNORE; /** * @see #setStatsPropertyPrefix */ private String statsPropertyPrefix; /** * */ public JUnit4() { resources = new Resources(); } /** * What should be done on unexpected JVM output? JVM may write directly to the * original descriptors, bypassing redirections of System.out and System.err. Typically, * these messages will be important and should fail the build (permgen space exceeded, * compiler errors, crash dumps). However, certain legitimate logs (gc activity, class loading * logs) are also printed to these streams so sometimes the output can be ignored. * *

Allowed values (any comma-delimited combination of): {@link JvmOutputAction} * constants. */ public void setJvmOutputAction(String jvmOutputActions) { EnumSet actions = EnumSet.noneOf(JvmOutputAction.class); for (String s : jvmOutputActions.split("[\\,\\ ]+")) { s = s.trim().toUpperCase(Locale.ENGLISH); actions.add(JvmOutputAction.valueOf(s)); } this.jvmOutputAction = actions; } /** * If set to true, any sysout and syserr calls will be written to original * output and error streams (and in effect will appear as "jvm output". By default * sysout and syserrs are captured and proxied to the event stream to be synchronized * with other test events but occasionally one may want to synchronize them with direct * JVM output (to synchronize with compiler output or GC output for example). */ public void setSysouts(boolean sysouts) { this.sysouts = sysouts; } /** * Enables a debug stream from each forked JVM. This will create an additional file * next to each events file. For debugging the framework only, not a general-purpose setting. */ public void setDebugStream(boolean debugStream) { this.debugStream = debugStream; } /** * Allow or disallow duplicate suite names in resource collections. By default this option * is true because certain ANT-compatible report types (like XML reports) * will have a problem with duplicate suite names (will overwrite files). */ public void setUniqueSuiteNames(boolean uniqueSuiteNames) { this.uniqueSuiteNames = uniqueSuiteNames; } /** * @see #setUniqueSuiteNames(boolean) */ public boolean isUniqueSuiteNames() { return uniqueSuiteNames; } /** * Specifies the ratio of suites moved to dynamic assignment list. A dynamic * assignment list dispatches suites to the first idle slave JVM. Theoretically * this is an optimal strategy, but it is usually better to have some static assignments * to avoid communication costs. * *

A ratio of 0 means only static assignments are used. A ratio of 1 means * only dynamic assignments are used. * *

The list of dynamic assignments is sorted by decreasing cost (always) and * is inherently prone to race conditions in distributing suites. Should there * be an error based on suite-dependency it will not be directly repeatable. In such * case use the per-slave-jvm list of suites file dumped to disk for each slave JVM. * (see {@link #setLeaveTemporary(boolean)}). */ public void setDynamicAssignmentRatio(float ratio) { if (ratio < 0 || ratio > 1) { throw new IllegalArgumentException("Dynamic assignment ratio must be " + "between 0 (only static assignments) to 1 (fully dynamic assignments)."); } this.dynamicAssignmentRatio = ratio; } /** * The number of parallel slaves. Can be set to a constant "max" for the * number of cores returned from {@link Runtime#availableProcessors()} or * "auto" for sensible defaults depending on the number of cores. * The default is a single subprocess. * *

Note that this setting forks physical JVM processes so it multiplies the * requirements for heap memory, IO, etc. */ public void setParallelism(String parallelism) { this.parallelism = parallelism; } /** * Property to set to "true" if there is a failure in a test. */ public void setFailureProperty(String failureProperty) { this.failureProperty = failureProperty; } /** * Do not propagate the old environment when new environment variables are specified. */ public void setNewEnvironment(boolean v) { this.newEnvironment = v; } /** * Initial random seed used for shuffling test suites and other sources * of pseudo-randomness. If not set, any random value is set. * *

The seed's format is compatible with {@link RandomizedRunner} so that * seed can be fixed for suites and methods alike. */ public void setSeed(String randomSeed) { if (!Strings.isNullOrEmpty(getProject().getUserProperty(SYSPROP_RANDOM_SEED()))) { String userProperty = getProject().getUserProperty(SYSPROP_RANDOM_SEED()); if (!userProperty.equals(randomSeed)) { log("Ignoring seed attribute because it is overridden by user properties.", Project.MSG_WARN); } } else if (!Strings.isNullOrEmpty(randomSeed)) { this.random = randomSeed; } } /** * Initializes custom prefix for all junit4 properties. This must be consistent * across all junit4 invocations if done from the same classpath. Use only when REALLY needed. */ public void setPrefix(String prefix) { if (!Strings.isNullOrEmpty(getProject().getUserProperty(SYSPROP_PREFIX()))) { log("Ignoring prefix attribute because it is overridden by user properties.", Project.MSG_WARN); } else { SysGlobals.initializeWith(prefix); } } /** * @see #setSeed(String) */ public String getSeed() { return random; } /** * Predictably shuffle tests order after balancing. This will help in spreading * lighter and heavier tests over a single slave's execution timeline while * still keeping the same tests order depending on the seed. */ public void setShuffleOnSlave(boolean shuffle) { this.shuffleOnSlave = shuffle; } /* * */ @Override public void setProject(Project project) { super.setProject(project); this.resources.setProject(project); this.classpath = new Path(getProject()); this.bootclasspath = new Path(getProject()); } /** * Prints the summary of all executed, ignored etc. tests at the end. */ public void setPrintSummary(boolean printSummary) { this.printSummary = printSummary; } /** * Stop the build process if there were failures or errors during test execution. */ public void setHaltOnFailure(boolean haltOnFailure) { this.haltOnFailure = haltOnFailure; } /** * Set the maximum memory to be used by all forked JVMs. * * @param max * the value as defined by -mx or -Xmx in the java * command line options. */ public void setMaxmemory(String max) { if (!Strings.isNullOrEmpty(max)) { getCommandline().setMaxmemory(max); } } /** * Set to true to leave temporary files for diagnostics. */ public void setLeaveTemporary(boolean leaveTemporary) { this.leaveTemporary = leaveTemporary; } /** * Add an additional argument to any forked JVM. */ public Commandline.Argument createJvmarg() { return getCommandline().createVmArgument(); } /** * The directory to invoke forked VMs in. */ public void setDir(File dir) { this.dir = dir; } /** * The directory to store temporary files in. */ public void setTempDir(File tempDir) { this.tempDir = tempDir; } /** * What to do when no tests were executed (all tests were ignored)? * @see NoTestsAction */ public void setIfNoTests(String value) { try { ifNoTests = NoTestsAction.valueOf(value.toUpperCase(Locale.ROOT)); } catch (IllegalArgumentException e) { throw new BuildException("Invalid value (one of " + Arrays.toString(NoTestsAction.values()) + " accepted): " + value); } } /** * A {@link org.apache.tools.ant.types.Environment.Variable} with an additional * attribute specifying whether or not empty values should be propagated or ignored. */ public static class ExtendedVariable extends Environment.Variable { private boolean ignoreEmptyValue = false; public void setIgnoreEmpty(boolean ignoreEmptyValue) { this.ignoreEmptyValue = ignoreEmptyValue; } public boolean shouldIgnore() { return ignoreEmptyValue && Strings.isNullOrEmpty(getValue()); } @Override public String toString() { return getContent() + " (ignoreEmpty=" + ignoreEmptyValue + ")"; } } /** * Adds a system property to any forked JVM. */ public void addConfiguredSysproperty(ExtendedVariable sysp) { if (!sysp.shouldIgnore()) { getCommandline().addSysproperty(sysp); } } /** * A {@link PropertySet} with an additional * attribute specifying whether or not empty values should be propagated or ignored. */ public static class ExtendedPropertySet extends PropertySet { private boolean ignoreEmptyValue = false; public void setIgnoreEmpty(boolean ignoreEmptyValue) { this.ignoreEmptyValue = ignoreEmptyValue; } @Override public Properties getProperties() { Properties properties = super.getProperties(); Properties clone = new Properties(); for (String s : properties.stringPropertyNames()) { String value = (String) properties.get(s); if (ignoreEmptyValue && Strings.isNullOrEmpty(value)) { continue; } else { clone.setProperty(s, value); } } return clone; } } /** * Adds a set of properties that will be used as system properties that tests * can access. * * This might be useful to transfer Ant properties to the testcases. */ public void addConfiguredSyspropertyset(ExtendedPropertySet sysp) { getCommandline().addSyspropertyset(sysp); } /** * The command used to invoke the Java Virtual Machine, default is 'java'. The * command is resolved by java.lang.Runtime.exec(). */ public void setJvm(String jvm) { if (!Strings.isNullOrEmpty(jvm)) { getCommandline().setVm(jvm); } } /** * If set to true each slave JVM gets a separate working directory * under whatever is set in {@link #setDir(File)}. The directory naming for each slave * follows: "Snum", where num is slave's number. Directories are created * automatically and removed unless {@link #setLeaveTemporary(boolean)} is set to * true. */ public void setIsolateWorkingDirectories(boolean isolateWorkingDirectories) { this.isolateWorkingDirectories = isolateWorkingDirectories; } /** * Adds an environment variable; used when forking. */ public void addEnv(ExtendedVariable var) { env.addVariable(var); } /** * Adds a set of tests based on pattern matching. */ public void addFileSet(FileSet fs) { add(fs); if (fs.getProject() == null) { fs.setProject(getProject()); } } /** * Adds a set of tests based on pattern matching. */ public void add(ResourceCollection rc) { resources.add(rc); } /** * Creates a new list of listeners. */ public ListenersList createListeners() { return new ListenersList(listeners); } /** * Add assertions to tests execution. */ public void addAssertions(Assertions asserts) { if (getCommandline().getAssertions() != null) { throw new BuildException("Only one assertion declaration is allowed"); } getCommandline().setAssertions(asserts); } /** * Creates a new list of balancers. */ public BalancersList createBalancers() { return new BalancersList(balancers); } /** * Adds path to classpath used for tests. * * @return reference to the classpath in the embedded java command line */ public Path createClasspath() { return classpath.createPath(); } /** * Adds a path to the bootclasspath. * * @return reference to the bootclasspath in the embedded java command line */ public Path createBootclasspath() { return bootclasspath.createPath(); } /* ANT-junit compat only. */ public void setFork(boolean fork) { warnUnsupported("fork"); } public void setForkmode(String forkMode) { warnUnsupported("forkmode"); } public void setHaltOnError(boolean haltOnError) { warnUnsupported("haltonerror"); } public void setFiltertrace(boolean filterTrace) { warnUnsupported("filtertrace"); log("Hint: report listeners have stack filtering options.", Project.MSG_WARN); } public void setTimeout(String v) { warnUnsupported("timeout"); } public void setIncludeantruntime(String v) { warnUnsupported("includeantruntime"); } public void setShowoutput(String v) { warnUnsupported("showoutput"); } public void setOutputtoformatters(String v) { warnUnsupported("outputtoformatters"); } public void setReloading(String v) { warnUnsupported("reloading"); } public void setClonevm(String v) { warnUnsupported("clonevm"); } public void setErrorproperty(String v) { warnUnsupported("errorproperty"); } public void setLogfailedtests(String v) { warnUnsupported("logfailedtests"); } public void setEnableTestListenerEvents(String v) { warnUnsupported("enableTestListenerEvents"); } public Object createFormatter() { throw new BuildException(" elements are not supported by . " + "Refer to the documentation about listeners and reports."); } public Object createTest() { throw new BuildException(" elements are not supported by . " + "Use regular ANT resource collections to point at individual tests or their groups."); } public Object createBatchtest() { throw new BuildException(" elements are not supported by . " + "Use regular ANT resource collections to point at individual tests or their groups."); } private void warnUnsupported(String attName) { log("The '" + attName + "' attribute is not supported by .", Project.MSG_WARN); } /** * Sets the heartbeat used to detect inactive/ hung forked tests (JVMs) to the given * number of seconds. The heartbeat detects * no-event intervals and will report them to listeners. Notably, {@link TextReport} report will * emit heartbeat information (to a file or console). * *

Setting the heartbeat to zero means no detection. */ public void setHeartbeat(long heartbeat) { this.heartbeat = heartbeat; } /** * Sets the property prefix to which test statistics are saved. */ public void setStatsPropertyPrefix(String statsPropertyPrefix) { this.statsPropertyPrefix = statsPropertyPrefix; } @Override public void execute() throws BuildException { validateJUnit4(); validateArguments(); // Initialize random if not already provided. if (random == null) { this.random = com.google.common.base.Objects.firstNonNull( Strings.emptyToNull(getProject().getProperty(SYSPROP_RANDOM_SEED())), SeedUtils.formatSeed(new Random().nextLong())); } masterSeed(); // Say hello and continue. log(" says " + RandomPicks.randomFrom(new Random(masterSeed()), WELCOME_MESSAGES) + " Master seed: " + getSeed(), Project.MSG_INFO); // Pass the random seed property. createJvmarg().setValue("-D" + SYSPROP_PREFIX() + "=" + CURRENT_PREFIX()); createJvmarg().setValue("-D" + SYSPROP_RANDOM_SEED() + "=" + random); // Resolve paths first. this.classpath = resolveFiles(classpath); this.bootclasspath = resolveFiles(bootclasspath); getCommandline().createClasspath(getProject()).add(classpath); getCommandline().createBootclasspath(getProject()).add(bootclasspath); // Setup a class loader over test classes. This will be used for loading annotations // and referenced classes. This is kind of ugly, but mirroring annotation content will // be even worse and Description carries these. testsClassLoader = new AntClassLoader( this.getClass().getClassLoader(), getProject(), getCommandline().getClasspath(), true); // Pass method filter if any. String testMethodFilter = Strings.emptyToNull(getProject().getProperty(SYSPROP_TESTMETHOD())); if (testMethodFilter != null) { Environment.Variable v = new Environment.Variable(); v.setKey(SYSPROP_TESTMETHOD()); v.setValue(testMethodFilter); getCommandline().addSysproperty(v); } // Process test classes and resources. long start = System.currentTimeMillis(); final TestsCollection testCollection = processTestResources(); final EventBus aggregatedBus = new EventBus("aggregated"); final TestsSummaryEventListener summaryListener = new TestsSummaryEventListener(); aggregatedBus.register(summaryListener); for (Object o : listeners) { if (o instanceof ProjectComponent) { ((ProjectComponent) o).setProject(getProject()); } if (o instanceof AggregatedEventListener) { ((AggregatedEventListener) o).setOuter(this); } aggregatedBus.register(o); } if (testCollection.testClasses.isEmpty()) { aggregatedBus.post(new AggregatedQuitEvent()); } else { start = System.currentTimeMillis(); // Check if we allow duplicate suite names. Some reports (ANT compatible XML // reports) will have a problem with duplicate suite names, for example. if (uniqueSuiteNames) { testCollection.onlyUniqueSuiteNames(); } final int jvmCount = determineForkedJvmCount(testCollection); final List slaveInfos = Lists.newArrayList(); for (int jvmid = 0; jvmid < jvmCount; jvmid++) { final ForkedJvmInfo slaveInfo = new ForkedJvmInfo(jvmid, jvmCount); slaveInfos.add(slaveInfo); } if (jvmCount > 1 && uniqueSuiteNames && testCollection.hasReplicatedSuites()) { throw new BuildException(String.format(Locale.ENGLISH, "There are test suites that request JVM replication and the number of forked JVMs %d is larger than 1. Run on a single JVM.", jvmCount)); } // Prepare a pool of suites dynamically dispatched to slaves as they become idle. final Deque stealingQueue = new ArrayDeque(loadBalanceSuites(slaveInfos, testCollection, balancers)); aggregatedBus.register(new Object() { @Subscribe public void onSlaveIdle(SlaveIdle slave) { if (stealingQueue.isEmpty()) { slave.finished(); } else { String suiteName = stealingQueue.pop(); slave.newSuite(suiteName); } } }); // Check for filtering expressions. @SuppressWarnings("unchecked") Vector vv = getCommandline().getSystemProperties().getVariablesVector(); for (Variable v : vv) { if (SysGlobals.SYSPROP_TESTFILTER().equals(v.getKey())) { try { Node root = new FilterExpressionParser().parse(v.getValue()); log("Parsed test filtering expression: " + root.toExpression(), Project.MSG_INFO); } catch (Exception e) { log("Could not parse filtering expression: " + v.getValue(), Project.MSG_WARN); } } } // Create callables for the executor. final List> slaves = Lists.newArrayList(); for (int slave = 0; slave < jvmCount; slave++) { final ForkedJvmInfo slaveInfo = slaveInfos.get(slave); slaves.add(new Callable() { @Override public Void call() throws Exception { executeSlave(slaveInfo, aggregatedBus); return null; } }); } ExecutorService executor = Executors.newCachedThreadPool(); aggregatedBus.post(new AggregatedStartEvent(slaves.size(), // TODO: this doesn't account for replicated suites. testCollection.testClasses.size())); try { List> all = executor.invokeAll(slaves); executor.shutdown(); for (int i = 0; i < slaves.size(); i++) { Future f = all.get(i); try { f.get(); } catch (ExecutionException e) { slaveInfos.get(i).executionError = e.getCause(); } } } catch (InterruptedException e) { log("Master interrupted? Weird.", Project.MSG_ERR); } aggregatedBus.post(new AggregatedQuitEvent()); for (ForkedJvmInfo si : slaveInfos) { if (si.start > 0 && si.end > 0) { log(String.format(Locale.ENGLISH, "JVM J%d: %8.2f .. %8.2f = %8.2fs", si.id, (si.start - start) / 1000.0f, (si.end - start) / 1000.0f, (si.getExecutionTime() / 1000.0f)), Project.MSG_INFO); } } log("Execution time total: " + Duration.toHumanDuration( (System.currentTimeMillis() - start))); ForkedJvmInfo slaveInError = null; for (ForkedJvmInfo i : slaveInfos) { if (i.executionError != null) { log("ERROR: JVM J" + i.id + " ended with an exception, command line: " + i.getCommandLine()); log("ERROR: JVM J" + i.id + " ended with an exception: " + Throwables.getStackTraceAsString(i.executionError), Project.MSG_ERR); if (slaveInError == null) { slaveInError = i; } } } if (slaveInError != null) { throw new BuildException("At least one slave process threw an exception, first: " + slaveInError.executionError.getMessage(), slaveInError.executionError); } } final TestsSummary testsSummary = summaryListener.getResult(); if (printSummary) { log("Tests summary: " + testsSummary, Project.MSG_INFO); } if (!testsSummary.isSuccessful()) { if (!Strings.isNullOrEmpty(failureProperty)) { getProject().setNewProperty(failureProperty, "true"); } if (haltOnFailure) { throw new BuildException("There were test failures: " + testsSummary); } } if (!leaveTemporary) { for (File f : temporaryFiles) { try { if (f != null) { if (!FileUtils.deleteQuietly(f)) throw new IOException(); } } catch (IOException e) { log("Could not remove temporary path: " + f.getAbsolutePath(), Project.MSG_WARN); } } } if (statsPropertyPrefix != null) { Project p = getProject(); p.setNewProperty(statsPropertyPrefix + ".tests", Integer.toString(testsSummary.tests)); p.setNewProperty(statsPropertyPrefix + ".errors", Integer.toString(testsSummary.errors)); p.setNewProperty(statsPropertyPrefix + ".failures", Integer.toString(testsSummary.failures)); p.setNewProperty(statsPropertyPrefix + ".ignores", Integer.toString(testsSummary.ignores)); p.setNewProperty(statsPropertyPrefix + ".suites", Integer.toString(testsSummary.suites)); p.setNewProperty(statsPropertyPrefix + ".assumptions", Integer.toString(testsSummary.assumptions)); p.setNewProperty(statsPropertyPrefix + ".suiteErrors", Integer.toString(testsSummary.suiteErrors)); p.setNewProperty(statsPropertyPrefix + ".nonIgnored", Integer.toString(testsSummary.getNonIgnoredTestsCount())); p.setNewProperty(statsPropertyPrefix + ".successful", Boolean.toString(testsSummary.isSuccessful())); } int executedTests = testsSummary.getNonIgnoredTestsCount(); if (executedTests == 0) { String message = "There were no executed tests: " + testsSummary; switch (ifNoTests) { case FAIL: throw new BuildException(message); case WARN: log(message, Project.MSG_WARN); break; case IGNORE: break; default: throw new RuntimeException("Unreachable case clause: " + ifNoTests); } } } /** * Validate arguments. */ private void validateArguments() { File tempDir = getTempDir(); if (tempDir == null) { throw new BuildException("Temporary directory cannot be null."); } if (tempDir.exists()) { if (!tempDir.isDirectory()) { throw new BuildException("Temporary directory is not a folder: " + tempDir.getAbsolutePath()); } } else { if (!tempDir.mkdirs()) { throw new BuildException("Failed to create temporary directory: " + tempDir.getAbsolutePath()); } } // TODO: we should probably add validation for the entire set of attrs... } /** * Validate JUnit4 presence in a concrete version. */ private void validateJUnit4() throws BuildException { try { Class clazz = Class.forName("org.junit.runner.Description"); if (!Serializable.class.isAssignableFrom(clazz)) { throw new BuildException("At least JUnit version 4.10 is required on junit4's taskdef classpath."); } } catch (ClassNotFoundException e) { throw new BuildException("JUnit JAR must be added to junit4 taskdef's classpath."); } } /** * Perform load balancing of the set of suites. Sets {@link ForkedJvmInfo#testSuites} * to suites preassigned to a given slave and returns a pool of suites * that should be load-balanced dynamically based on job stealing. */ private List loadBalanceSuites(List jvmInfo, TestsCollection testsCollection, List balancers) { // Order test suites identically for balancers. // and split into replicated and non-replicated suites. Multimap partitioned = sortAndSplitReplicated(testsCollection.testClasses); Function extractClassName = new Function() { @Override public String apply(TestClass input) { return input.className; } }; Collection replicated = Collections2.transform(partitioned.get(true), extractClassName); Collection suites = Collections2.transform(partitioned.get(false), extractClassName); final List balancersWithFallback = Lists.newArrayList(balancers); balancersWithFallback.add(new RoundRobinBalancer()); // Go through all the balancers, the first one to assign a suite wins. final Multiset remaining = HashMultiset.create(suites); final Map> perJvmAssignments = Maps.newHashMap(); for (ForkedJvmInfo si : jvmInfo) { perJvmAssignments.put(si.id, Lists. newArrayList()); } final int jvmCount = jvmInfo.size(); for (SuiteBalancer balancer : balancersWithFallback) { balancer.setOwner(this); final List assignments = balancer.assign( Collections.unmodifiableCollection(remaining), jvmCount, masterSeed()); for (Assignment e : assignments) { if (e == null) { throw new RuntimeException("Balancer must return non-null assignments."); } if (!remaining.remove(e.suiteName)) { throw new RuntimeException("Balancer must return suite name as a key: " + e.suiteName); } log(String.format(Locale.ENGLISH, "Assignment hint: J%-2d (cost %5d) %s (by %s)", e.slaveId, e.estimatedCost, e.suiteName, balancer.getClass().getSimpleName()), Project.MSG_VERBOSE); perJvmAssignments.get(e.slaveId).add(e); } } if (remaining.size() != 0) { throw new RuntimeException("Not all suites assigned?: " + remaining); } if (shuffleOnSlave) { // Shuffle suites on slaves so that the result is always the same wrt master seed // (sort first, then shuffle with a constant seed). for (List assignments : perJvmAssignments.values()) { Collections.sort(assignments); Collections.shuffle(assignments, new Random(this.masterSeed())); } } // Take a fraction of suites scheduled as last on each slave and move them to a common // job-stealing queue. List stealingQueueWithHints = Lists.newArrayList(); for (ForkedJvmInfo si : jvmInfo) { final List assignments = perJvmAssignments.get(si.id); int moveToCommon = (int) (assignments.size() * dynamicAssignmentRatio); if (moveToCommon > 0) { final List movedToCommon = assignments.subList(assignments.size() - moveToCommon, assignments.size()); for (Assignment a : movedToCommon) { stealingQueueWithHints.add(new SuiteHint(a.suiteName, a.estimatedCost)); } movedToCommon.clear(); } final ArrayList slaveSuites = (si.testSuites = Lists.newArrayList()); for (Assignment a : assignments) { slaveSuites.add(a.suiteName); } } // Sort stealing queue according to descending cost. Collections.sort(stealingQueueWithHints, SuiteHint.DESCENDING_BY_WEIGHT); // Append all replicated suites to each forked JVM, AFTER we process the stealing queue // to enforce all replicated suites run on each bound JVM. if (!replicated.isEmpty()) { for (ForkedJvmInfo si : jvmInfo) { for (String suite : replicated) { si.testSuites.add(suite); } if (shuffleOnSlave) { // Shuffle suites on slaves so that the result is always the same wrt master seed // (sort first, then shuffle with a constant seed). Collections.shuffle(si.testSuites, new Random(this.masterSeed())); } } } // Dump scheduling information. for (ForkedJvmInfo si : jvmInfo) { log("Forked JVM J" + si.id + " assignments (after shuffle):", Project.MSG_VERBOSE); for (String suiteName : si.testSuites) { log(" " + suiteName, Project.MSG_VERBOSE); } } log("Stealing queue:", Project.MSG_VERBOSE); for (SuiteHint suiteHint : stealingQueueWithHints) { log(" " + suiteHint.suiteName + " " + suiteHint.cost, Project.MSG_VERBOSE); } List stealingQueue = Lists.newArrayListWithCapacity(stealingQueueWithHints.size()); for (SuiteHint suiteHint : stealingQueueWithHints) { stealingQueue.add(suiteHint.suiteName); } return stealingQueue; } private Multimap sortAndSplitReplicated(List testClasses) { List sorted = Ordering.natural() .onResultOf(new Function() { @Override public String apply(TestClass input) { return input.className + ";" + input.replicate; } }) .sortedCopy(testClasses); return Multimaps.index(sorted, new Function() { @Override public Boolean apply(TestClass t) { return t.replicate; } }); } /** * Return the master seed of {@link #getSeed()}. */ private long masterSeed() { long[] seeds = SeedUtils.parseSeedChain(getSeed()); if (seeds.length < 1) { throw new BuildException("Random seed is required."); } return seeds[0]; } /** * Resolve all files from a given path and simplify its definition. */ private Path resolveFiles(Path path) { Path cloned = new Path(getProject()); for (String location : path.list()) { cloned.createPathElement().setLocation(new File(location)); } return cloned; } /** * Determine how many forked JVMs to use. */ private int determineForkedJvmCount(TestsCollection testCollection) { int cores = Runtime.getRuntime().availableProcessors(); int jvmCount; if (this.parallelism.equals(PARALLELISM_AUTO)) { if (cores >= 8) { // Maximum parallel jvms is 4, conserve some memory and memory bandwidth. jvmCount = 4; } else if (cores >= 4) { // Make some space for the aggregator. jvmCount = 3; } else { // even for dual cores it usually makes no sense to fork more than one // JVM. jvmCount = 1; } } else if (this.parallelism.equals(PARALLELISM_MAX)) { jvmCount = Runtime.getRuntime().availableProcessors(); } else { try { jvmCount = Math.max(1, Integer.parseInt(parallelism)); } catch (NumberFormatException e) { throw new BuildException("parallelism must be 'auto', 'max' or a valid integer: " + parallelism); } } if (!testCollection.hasReplicatedSuites()) { jvmCount = Math.min(testCollection.testClasses.size(), jvmCount); } return jvmCount; } /** * Attach listeners and execute a slave process. */ private void executeSlave(final ForkedJvmInfo slave, final EventBus aggregatedBus) throws Exception { final String uniqueSeed = new SimpleDateFormat("yyyyMMdd_HHmmss_SSS").format(new Date()); final File classNamesFile = tempFile(uniqueSeed, "junit4-J" + slave.id, ".suites", getTempDir()); temporaryFiles.add(classNamesFile); final File classNamesDynamic = tempFile(uniqueSeed, "junit4-J" + slave.id, ".dynamic-suites", getTempDir()); final File streamsBufferFile = tempFile(uniqueSeed, "junit4-J" + slave.id, ".spill", getTempDir()); // Dump all test class names to a temporary file. String testClassPerLine = Joiner.on("\n").join(slave.testSuites); log("Test class names:\n" + testClassPerLine, Project.MSG_VERBOSE); Files.write(testClassPerLine, classNamesFile, Charsets.UTF_8); // Prepare command line for java execution. CommandlineJava commandline; commandline = (CommandlineJava) getCommandline().clone(); commandline.createClasspath(getProject()).add(addSlaveClasspath()); commandline.setClassname(SlaveMainSafe.class.getName()); if (slave.slaves == 1) { commandline.createArgument().setValue(SlaveMain.OPTION_FREQUENT_FLUSH); } // Set up full output files. File sysoutFile = tempFile(uniqueSeed, "junit4-J" + slave.id, ".sysout", getTempDir()); File syserrFile = tempFile(uniqueSeed, "junit4-J" + slave.id, ".syserr", getTempDir()); // Set up communication channel. File eventFile = tempFile(uniqueSeed, "junit4-J" + slave.id, ".events", getTempDir()); temporaryFiles.add(eventFile); commandline.createArgument().setValue(SlaveMain.OPTION_EVENTSFILE); commandline.createArgument().setFile(eventFile); if (sysouts) { commandline.createArgument().setValue(SlaveMain.OPTION_SYSOUTS); } if (debugStream) { commandline.createArgument().setValue(SlaveMain.OPTION_DEBUGSTREAM); } InputStream eventStream = new TailInputStream(eventFile); // Set up input suites file. commandline.createArgument().setValue("@" + classNamesFile.getAbsolutePath()); // Emit command line before -stdin to avoid confusion. slave.slaveCommandLine = escapeAndJoin(commandline.getCommandline()); log("Forked JVM process command line (may need escape sequences for your shell):\n" + slave.slaveCommandLine, Project.MSG_VERBOSE); commandline.createArgument().setValue(SlaveMain.OPTION_STDIN); final EventBus eventBus = new EventBus("slave-" + slave.id); final DiagnosticsListener diagnosticsListener = new DiagnosticsListener(slave, this); eventBus.register(diagnosticsListener); eventBus.register(new AggregatingListener(aggregatedBus, slave)); final AtomicReference clientCharset = new AtomicReference(); final AtomicBoolean clientWithLimitedCharset = new AtomicBoolean(); final PrintWriter w = new PrintWriter(Files.newWriter(classNamesDynamic, Charsets.UTF_8)); eventBus.register(new Object() { @Subscribe public void onIdleSlave(final SlaveIdle idleSlave) { aggregatedBus.post(new SlaveIdle() { @Override public void finished() { idleSlave.finished(); } @Override public void newSuite(String suiteName) { if (!clientCharset.get().newEncoder().canEncode(suiteName)) { clientWithLimitedCharset.set(true); log("Forked JVM J" + slave.id + " skipped suite (cannot encode suite name in charset " + clientCharset.get() + "): " + suiteName, Project.MSG_WARN); return; } log("Forked JVM J" + slave.id + " stole suite: " + suiteName, Project.MSG_VERBOSE); w.println(suiteName); w.flush(); idleSlave.newSuite(suiteName); } }); } @Subscribe public void onBootstrap(final BootstrapEvent e) { Charset cs = Charset.forName(((BootstrapEvent) e).getDefaultCharsetName()); clientCharset.set(cs); slave.start = System.currentTimeMillis(); slave.setBootstrapEvent(e); aggregatedBus.post(new ChildBootstrap(slave)); } @Subscribe public void receiveQuit(QuitEvent e) { slave.end = System.currentTimeMillis(); } }); Closer closer = Closer.create(); closer.register(eventStream); closer.register(w); try { OutputStream sysout = closer.register(new BufferedOutputStream(new FileOutputStream(sysoutFile))); OutputStream syserr = closer.register(new BufferedOutputStream(new FileOutputStream(syserrFile))); RandomAccessFile streamsBuffer = closer.register(new RandomAccessFile(streamsBufferFile, "rw")); Execute execute = forkProcess(slave, eventBus, commandline, eventStream, sysout, syserr, streamsBuffer); log("Forked JVM J" + slave.id + " finished with exit code: " + execute.getExitValue(), Project.MSG_DEBUG); if (execute.isFailure()) { final int exitStatus = execute.getExitValue(); switch (exitStatus) { case SlaveMain.ERR_NO_JUNIT: throw new BuildException("Forked JVM's classpath must include a junit4 JAR."); case SlaveMain.ERR_OLD_JUNIT: throw new BuildException("Forked JVM's classpath must use JUnit 4.10 or newer."); default: Closeables.close(sysout, false); Closeables.close(syserr, false); StringBuilder message = new StringBuilder(); if (exitStatus == SlaveMain.ERR_OOM) { message.append("Forked JVM ran out of memory."); } else { message.append("Forked process returned with error code: ").append(exitStatus).append("."); } if (sysoutFile.length() > 0 || syserrFile.length() > 0) { if (exitStatus != SlaveMain.ERR_OOM) { message.append(" Very likely a JVM crash. "); } if (jvmOutputAction.contains(JvmOutputAction.PIPE)) { message.append(" Process output piped in logs above."); } else if (!jvmOutputAction.contains(JvmOutputAction.IGNORE)) { if (sysoutFile.length() > 0) { message.append(" See process stdout at: " + sysoutFile.getAbsolutePath()); } if (syserrFile.length() > 0) { message.append(" See process stderr at: " + syserrFile.getAbsolutePath()); } } } throw new BuildException(message.toString()); } } } catch (Throwable t) { throw closer.rethrow(t); } finally { try { closer.close(); } finally { Files.asByteSource(classNamesDynamic).copyTo(Files.asByteSink(classNamesFile, FileWriteMode.APPEND)); classNamesDynamic.delete(); streamsBufferFile.delete(); // Check sysout/syserr lengths. checkJvmOutput(sysoutFile, slave, "stdout"); checkJvmOutput(syserrFile, slave, "stderr"); } } if (!diagnosticsListener.quitReceived()) { throw new BuildException("Quit event not received from the forked process? This may indicate JVM crash or runner bugs."); } if (clientWithLimitedCharset.get() && dynamicAssignmentRatio > 0) { throw new BuildException("Forked JVM J" + slave.id + " was not be able to decode class names when using" + " charset: " + clientCharset + ". Do not use " + "dynamic suite balancing to work around this problem (-DdynamicAssignmentRatio=0)."); } } private void checkJvmOutput(File file, ForkedJvmInfo slave, String fileName) { if (file.length() > 0) { String message = "JVM J" + slave.id + ": " + fileName + " was not empty, see: " + file; if (jvmOutputAction.contains(JvmOutputAction.WARN)) { log(message, Project.MSG_WARN); } if (jvmOutputAction.contains(JvmOutputAction.PIPE)) { log(">>> JVM J" + slave.id + ": " + fileName + " (verbatim) ----", Project.MSG_INFO); try { // If file > 10 mb, stream directly. Otherwise use the logger. if (file.length() < 10 * (1024 * 1024)) { // Append to logger. log(Files.toString(file, slave.getCharset()), Project.MSG_INFO); } else { // Stream directly. CharStreams.copy(Files.newReader(file, slave.getCharset()), System.out); } } catch (IOException e) { log("Couldn't pipe file " + file + ": " + e.toString(), Project.MSG_INFO); } log("<<< JVM J" + slave.id + ": EOF ----", Project.MSG_INFO); } if (jvmOutputAction.contains(JvmOutputAction.IGNORE)) { file.delete(); } if (jvmOutputAction.contains(JvmOutputAction.FAIL)) { throw new BuildException(message); } return; } file.delete(); } private File tempFile(String uniqueSeed, String base, String suffix, File tempDir) throws IOException { int retry = 0; File finalName; do { if (retry > 0) { finalName = new File(tempDir, base + "-" + uniqueSeed + "_retry" + retry + suffix); } else { finalName = new File(tempDir, base + "-" + uniqueSeed + suffix); } } while (!finalName.createNewFile() && retry++ < 5); return finalName; } /** * Try to provide an escaped, ready-to-use shell line to repeat a given command line. */ private String escapeAndJoin(String[] commandline) { // TODO: we should try to escape special characters here, depending on the OS. StringBuilder b = new StringBuilder(); Pattern specials = Pattern.compile("[\\ ]"); for (String arg : commandline) { if (b.length() > 0) { b.append(" "); } if (specials.matcher(arg).find()) { b.append('"').append(arg).append('"'); } else { b.append(arg); } } return b.toString(); } /** * Execute a slave process. Pump events to the given event bus. */ private Execute forkProcess(ForkedJvmInfo slaveInfo, EventBus eventBus, CommandlineJava commandline, InputStream eventStream, OutputStream sysout, OutputStream syserr, RandomAccessFile streamsBuffer) { try { final LocalSlaveStreamHandler streamHandler = new LocalSlaveStreamHandler( eventBus, testsClassLoader, System.err, eventStream, sysout, syserr, heartbeat, streamsBuffer); // Add certain properties to allow identification of the forked JVM from within // the subprocess. This can be used for policy files etc. final File cwd = getWorkingDirectory(slaveInfo); Variable v = new Variable(); v.setKey(CHILDVM_SYSPROP_CWD); v.setFile(cwd.getAbsoluteFile()); commandline.addSysproperty(v); v = new Variable(); v.setKey(SysGlobals.CHILDVM_SYSPROP_JVM_ID); v.setValue(Integer.toString(slaveInfo.id)); commandline.addSysproperty(v); v = new Variable(); v.setKey(SysGlobals.CHILDVM_SYSPROP_JVM_COUNT); v.setValue(Integer.toString(slaveInfo.slaves)); commandline.addSysproperty(v); final Execute execute = new Execute(); execute.setCommandline(commandline.getCommandline()); execute.setVMLauncher(true); execute.setWorkingDirectory(cwd); execute.setStreamHandler(streamHandler); execute.setNewenvironment(newEnvironment); if (env.getVariables() != null) execute.setEnvironment(env.getVariables()); log("Starting JVM J" + slaveInfo.id, Project.MSG_DEBUG); execute.execute(); return execute; } catch (IOException e) { throw new BuildException("Could not execute slave process. Run ant with -verbose to get" + " the execution details.", e); } } private File getWorkingDirectory(ForkedJvmInfo slaveInfo) { File baseDir = (dir == null ? getProject().getBaseDir() : dir); final File slaveDir; if (isolateWorkingDirectories) { slaveDir = new File(baseDir, "J" + slaveInfo.id); slaveDir.mkdirs(); temporaryFiles.add(slaveDir); } else { slaveDir = baseDir; } return slaveDir; } /** * Resolve temporary folder. */ private File getTempDir() { if (this.tempDir == null) { if (this.dir != null) { this.tempDir = dir; } else { this.tempDir = getProject().getBaseDir(); } } return tempDir; } /** * Process test resources. If there are any test resources that are _not_ class files, * this will cause a build error. */ private TestsCollection processTestResources() { TestsCollection collection = new TestsCollection(); resources.setProject(getProject()); @SuppressWarnings("unchecked") Iterator iter = (Iterator) resources.iterator(); boolean javaSourceWarn = false; while (iter.hasNext()) { final Resource r = iter.next(); if (!r.isExists()) throw new BuildException("Test class resource does not exist?: " + r.getName()); try { if (r.getName().endsWith(".java")) { String pathname = r.getName(); String className = pathname.substring(0, pathname.length() - ".java".length()); className = className .replace(File.separatorChar, '.') .replace('/', '.') .replace('\\', '.'); collection.add(new TestClass(className)); if (!javaSourceWarn) { log("Source (.java) files used for naming source suites. This is discouraged, " + "use a resource collection pointing to .class files instead.", Project.MSG_INFO); javaSourceWarn = true; } } else { // Assume .class file. InputStream is = r.getInputStream(); if (!is.markSupported()) { is = new BufferedInputStream(is); } try { is.mark(4); if (is.read() != 0xca || is.read() != 0xfe || is.read() != 0xba || is.read() != 0xbe) { throw new BuildException("File does not start with a class magic 0xcafebabe: " + r.getName() + ", " + r.getLocation()); } is.reset(); // Hardcoded intentionally. final String REPLICATE_CLASS = "com.carrotsearch.randomizedtesting.annotations.ReplicateOnEachVm"; final TestClass testClass = new TestClass(); ClassReader reader = new ClassReader(is); ClassVisitor annotationVisitor = new ClassVisitor(Opcodes.ASM5) { @Override public AnnotationVisitor visitAnnotation(String desc, boolean visible) { String className = Type.getType(desc).getClassName(); if (className.equals(REPLICATE_CLASS)) { testClass.replicate = true; } return null; } }; reader.accept(annotationVisitor, ClassReader.SKIP_CODE | ClassReader.SKIP_DEBUG | ClassReader.SKIP_FRAMES); testClass.className = reader.getClassName().replace('/', '.'); log("Test class parsed: " + r.getName() + " as " + testClass.className, Project.MSG_DEBUG); collection.add(testClass); } finally { is.close(); } } } catch (IOException e) { throw new BuildException("Could not read or parse as Java class: " + r.getName() + ", " + r.getLocation()); } } String testClassFilter = Strings.emptyToNull(getProject().getProperty(SYSPROP_TESTCLASS())); if (testClassFilter != null) { ClassGlobFilter filter = new ClassGlobFilter(testClassFilter); for (Iterator i = collection.testClasses.iterator(); i.hasNext();) { if (!filter.shouldRun(Description.createSuiteDescription(i.next().className))) { i.remove(); } } } return collection; } /** * Returns the slave VM command line. */ private CommandlineJava getCommandline() { return slaveCommand; } /** * Adds a classpath source which contains the given resource. */ private Path addSlaveClasspath() { Path path = new Path(getProject()); String [] REQUIRED_SLAVE_CLASSES = { SlaveMain.class.getName(), Strings.class.getName(), MethodGlobFilter.class.getName(), Gson.class.getName(), TeeOutputStream.class.getName() }; for (String clazz : Arrays.asList(REQUIRED_SLAVE_CLASSES)) { String resource = clazz.replace(".", "/") + ".class"; File f = LoaderUtils.getResourceSource(getClass().getClassLoader(), resource); if (f != null) { path.createPath().setLocation(f); } else { throw new BuildException("Could not locate classpath for resource: " + resource); } } return path; } } ListenersList.java000066400000000000000000000007321235451432000352740ustar00rootroot00000000000000randomizedtesting-release-2.1.6/junit4-ant/src/main/java/com/carrotsearch/ant/tasks/junit4package com.carrotsearch.ant.tasks.junit4; import java.util.List; import com.carrotsearch.ant.tasks.junit4.listeners.AggregatedEventListener; public class ListenersList { private List listeners; public ListenersList(List listeners) { this.listeners = listeners; } /** * Adds a listener to the listeners list. * @param listener */ public void addConfigured(AggregatedEventListener listener) { listeners.add(listener); } } LocalSlaveStreamHandler.java000066400000000000000000000205231235451432000371670ustar00rootroot00000000000000randomizedtesting-release-2.1.6/junit4-ant/src/main/java/com/carrotsearch/ant/tasks/junit4package com.carrotsearch.ant.tasks.junit4; import java.io.*; import java.lang.Thread.UncaughtExceptionHandler; import java.nio.charset.Charset; import java.util.List; import java.util.concurrent.TimeUnit; import org.apache.tools.ant.taskdefs.ExecuteStreamHandler; import org.apache.tools.ant.taskdefs.StreamPumper; import com.carrotsearch.ant.tasks.junit4.events.*; import com.google.common.collect.Lists; import com.google.common.eventbus.EventBus; /** * Establish event passing with a subprocess and pump events to the bus. */ public class LocalSlaveStreamHandler implements ExecuteStreamHandler { private final EventBus eventBus; private final ClassLoader refLoader; private InputStream stdout; private InputStream stderr; /** raw input stream to the client. */ private OutputStream stdin; /** character-wrapped input stream to the client. */ private OutputStreamWriter stdinWriter; private final PrintStream warnStream; private final InputStream eventStream; private volatile boolean stopping; private List pumpers = Lists.newArrayList(); private final OutputStream sysout; private final OutputStream syserr; private final long heartbeat; private final RandomAccessFile streamsBuffer; private final OutputStream streamsBufferWrapper; public LocalSlaveStreamHandler( EventBus eventBus, ClassLoader classLoader, PrintStream warnStream, InputStream eventStream, OutputStream sysout, OutputStream syserr, long heartbeat, final RandomAccessFile streamsBuffer) { this.eventBus = eventBus; this.warnStream = warnStream; this.refLoader = classLoader; this.eventStream = eventStream; this.sysout = sysout; this.syserr = syserr; this.heartbeat = heartbeat; this.streamsBuffer = streamsBuffer; this.streamsBufferWrapper = new OutputStream() { @Override public void write(int b) throws IOException { streamsBuffer.write(b); } @Override public void write(byte[] b) throws IOException { streamsBuffer.write(b, 0, b.length); } @Override public void write(byte[] b, int off, int len) throws IOException { streamsBuffer.write(b, off, len); } }; } @Override public void setProcessErrorStream(InputStream is) throws IOException { this.stderr = is; } @Override public void setProcessOutputStream(InputStream is) throws IOException { this.stdout = is; } @Override public void setProcessInputStream(OutputStream os) throws IOException { this.stdin = os; } /** * A timestamp of last received event (GH-106). */ private volatile Long lastActivity; /** * Watchdog thread if heartbeat is to be measured. */ private Thread watchdog; /** * Client charset extracted from {@link BootstrapEvent}. */ private Charset clientCharset; @Override public void start() throws IOException { lastActivity = System.currentTimeMillis(); pumpers.add(new Thread(new StreamPumper(stdout, sysout), "pumper-stdout")); pumpers.add(new Thread(new StreamPumper(stderr, syserr), "pumper-stderr")); pumpers.add(new Thread("pumper-events") { public void run() { pumpEvents(eventStream); } }); if (heartbeat > 0) { pumpers.add(watchdog = new Thread("pumper-watchdog") { public void run() { final long heartbeatMillis = TimeUnit.SECONDS.toMillis(heartbeat); final long HEARTBEAT = Math.max(500, heartbeatMillis / 5); final long HEARTBEAT_EVENT_THRESHOLD = heartbeatMillis; try { long lastObservedUpdate = lastActivity; long reportDeadline = lastObservedUpdate + HEARTBEAT_EVENT_THRESHOLD; while (true) { Thread.sleep(HEARTBEAT); Long last = lastActivity; if (last == null) { break; // terminated. } if (last != lastObservedUpdate) { lastObservedUpdate = last; reportDeadline = last + HEARTBEAT_EVENT_THRESHOLD; } else { final long current = System.currentTimeMillis(); if (current >= reportDeadline) { eventBus.post(new LowLevelHeartBeatEvent(last, current)); reportDeadline = System.currentTimeMillis() + HEARTBEAT_EVENT_THRESHOLD; } } } } catch (InterruptedException e ) { // terminate on interrupt. } } }); } // Start all pumper threads. UncaughtExceptionHandler handler = new UncaughtExceptionHandler() { public void uncaughtException(Thread t, Throwable e) { warnStream.println("Unhandled exception in thread: " + t); e.printStackTrace(warnStream); } }; for (Thread t : pumpers) { t.setUncaughtExceptionHandler(handler); t.setDaemon(true); t.start(); } } private static class OnDiskStreamEvent implements IEvent, IStreamEvent { private final RandomAccessFile bufferFile; private long start; private long end; private EventType type; public OnDiskStreamEvent(EventType type, RandomAccessFile streamsBuffer, long start, long end) { this.bufferFile = streamsBuffer; this.start = start; this.end = end; this.type = type; } @Override public EventType getType() { return type; } @Override public void copyTo(OutputStream os) throws IOException { final long restorePosition = bufferFile.getFilePointer(); bufferFile.seek(start); try { long length = end - start; final byte [] buffer = new byte [(int) Math.min(length, 1024 * 4)]; while (length > 0) { int bytes = bufferFile.read(buffer, 0, (int) Math.min(length, buffer.length)); os.write(buffer, 0, bytes); length -= bytes; } } finally { bufferFile.seek(restorePosition); } } } /** * Pump events from event stream. */ void pumpEvents(InputStream eventStream) { try { Deserializer deserializer = new Deserializer(eventStream, refLoader); IEvent event = null; while ((event = deserializer.deserialize()) != null) { switch (event.getType()) { case APPEND_STDERR: case APPEND_STDOUT: // Ignore these two on activity heartbeats. GH-117 break; default: lastActivity = System.currentTimeMillis(); break; } try { switch (event.getType()) { case QUIT: eventBus.post(event); return; case IDLE: eventBus.post(new SlaveIdle(stdinWriter)); break; case BOOTSTRAP: clientCharset = Charset.forName(((BootstrapEvent) event).getDefaultCharsetName()); stdinWriter = new OutputStreamWriter(stdin, clientCharset); eventBus.post(event); break; case APPEND_STDERR: case APPEND_STDOUT: assert streamsBuffer.getFilePointer() == streamsBuffer.length(); final long bufferStart = streamsBuffer.getFilePointer(); IStreamEvent streamEvent = (IStreamEvent) event; streamEvent.copyTo(streamsBufferWrapper); final long bufferEnd = streamsBuffer.getFilePointer(); event = new OnDiskStreamEvent(event.getType(), streamsBuffer, bufferStart, bufferEnd); eventBus.post(event); break; default: eventBus.post(event); } } catch (Throwable t) { warnStream.println("Event bus dispatch error: " + t.toString()); t.printStackTrace(warnStream); } } lastActivity = null; } catch (Throwable e) { if (!stopping) { warnStream.println("Event stream error: " + e.toString()); e.printStackTrace(warnStream); } } } @Override public void stop() { lastActivity = null; stopping = true; try { // Terminate watchdog early. if (watchdog != null) { watchdog.interrupt(); } // Terminate all other pumpers. final int defaultDelay = 2000; for (Thread t : pumpers) { t.join(defaultDelay); t.interrupt(); } } catch (InterruptedException e) { // Don't wait. } } } PickFromListTask.java000066400000000000000000000065401235451432000356640ustar00rootroot00000000000000randomizedtesting-release-2.1.6/junit4-ant/src/main/java/com/carrotsearch/ant/tasks/junit4package com.carrotsearch.ant.tasks.junit4; import static com.carrotsearch.randomizedtesting.SysGlobals.SYSPROP_RANDOM_SEED; import java.util.List; import java.util.Random; import java.util.concurrent.atomic.AtomicInteger; import org.apache.tools.ant.*; import com.carrotsearch.randomizedtesting.SeedUtils; import com.carrotsearch.randomizedtesting.generators.RandomPicks; import com.google.common.base.Strings; import com.google.common.collect.Lists; /** * An ANT task to pick and fix the random seed in advance (for selecting * other derivative values, for example). */ public class PickFromListTask extends Task { /** * Nested value element. */ public final static class StringValue extends ProjectComponent { private String value = ""; public void addText(String value) { this.value += getProject().replaceProperties(value); } @Override public String toString() { return value; } } /** * Name of the property to set. */ private String propertyName; /** * Allow the property to be undefined as one of * the pick choices. */ private boolean allowUndefined = false; /** * Random seed to use. */ private String random; /** * Values to pick from. */ private List values = Lists.newArrayList(); /** * Execution ID used to permute the pick order for lists of identical length * and identical seed. */ private static AtomicInteger executionId = new AtomicInteger(); public void setProperty(String propertyName) { this.propertyName = propertyName; } public void setAllowUndefined(boolean allowUndefined) { this.allowUndefined = allowUndefined; } public void setSeed(String randomSeed) { if (!Strings.isNullOrEmpty(getProject().getUserProperty(SYSPROP_RANDOM_SEED()))) { String userProperty = getProject().getUserProperty(SYSPROP_RANDOM_SEED()); if (!userProperty.equals(randomSeed)) { log("Ignoring seed attribute because it is overridden by user properties.", Project.MSG_WARN); } } else if (!Strings.isNullOrEmpty(randomSeed)) { this.random = randomSeed; } } public StringValue createValue() { StringValue v = new StringValue(); values.add(v); return v; } /** * Execute the task. */ @Override public void execute() throws BuildException { validate(); if (allowUndefined) { values.add(null); } long permutedSeed = SeedUtils.parseSeedChain(random)[0]; permutedSeed ^= new Random(executionId.incrementAndGet()).nextLong(); StringValue pick = RandomPicks.randomFrom(new Random(permutedSeed), values); if (pick != null) { getProject().setProperty(propertyName, pick.toString()); } } /** * Validate arguments and state. */ private void validate() { if (Strings.emptyToNull(random) == null) { random = Strings.emptyToNull(getProject().getProperty(SYSPROP_RANDOM_SEED())); } if (random == null) { throw new BuildException("Required attribute 'seed' must not be empty. Look at ."); } long[] seeds = SeedUtils.parseSeedChain(random); if (seeds.length < 1) { throw new BuildException("Random seed is required."); } if (values.isEmpty() && !allowUndefined) { throw new BuildException("No values to pick from and allowUndefined=false."); } } } PickSeedTask.java000066400000000000000000000027161235451432000350060ustar00rootroot00000000000000randomizedtesting-release-2.1.6/junit4-ant/src/main/java/com/carrotsearch/ant/tasks/junit4package com.carrotsearch.ant.tasks.junit4; import java.util.Random; import org.apache.tools.ant.*; import com.carrotsearch.randomizedtesting.SeedUtils; import com.carrotsearch.randomizedtesting.SysGlobals; import com.google.common.base.Strings; /** * An ANT task to pick and fix the random seed in advance (for selecting * other derivative values, for example). */ public class PickSeedTask extends Task { /** * Name of the property to set. */ private String propertyName; /** * Picks a random seed and writes it to a given property. If the property * is already defined nothing is done. */ public void setProperty(String propertyName) { this.propertyName = propertyName; } /** * Execute the task. */ @Override public void execute() throws BuildException { validate(); String seedValue = Strings.emptyToNull(getProject().getProperty(propertyName)); if (seedValue == null) { seedValue = SeedUtils.formatSeed(new Random().nextLong()); log("Picking master seed for property '" + propertyName + "': " + seedValue, Project.MSG_VERBOSE); getProject().setProperty(propertyName, seedValue); } else { log("Seed property '" + propertyName + "' already defined: " + seedValue, Project.MSG_INFO); } } /** * Validate arguments and state. */ private void validate() { if (propertyName == null) { propertyName = SysGlobals.SYSPROP_RANDOM_SEED(); } } } Pluralize.java000066400000000000000000000003461235451432000344400ustar00rootroot00000000000000randomizedtesting-release-2.1.6/junit4-ant/src/main/java/com/carrotsearch/ant/tasks/junit4package com.carrotsearch.ant.tasks.junit4; public final class Pluralize { private Pluralize() {} public static String pluralize(int count, String word) { if (count != 1) { word += "s"; } return word; } } SlaveIdle.java000066400000000000000000000013131235451432000343340ustar00rootroot00000000000000randomizedtesting-release-2.1.6/junit4-ant/src/main/java/com/carrotsearch/ant/tasks/junit4package com.carrotsearch.ant.tasks.junit4; import java.io.IOException; import java.io.OutputStreamWriter; /** * An event published when a slave is idle and waits for new suite classes. */ class SlaveIdle { private OutputStreamWriter stdin; /** For delegation. */ SlaveIdle() { } public SlaveIdle(OutputStreamWriter stdin) { this.stdin = stdin; } public void finished() { try { stdin.close(); } catch (IOException e) { // Ignore, not much we can do. } } public void newSuite(String suiteName) { try { stdin.write(suiteName); stdin.write("\n"); stdin.flush(); } catch (IOException e) { throw new RuntimeException(e); } } } SuiteBalancer.java000066400000000000000000000027111235451432000352100ustar00rootroot00000000000000randomizedtesting-release-2.1.6/junit4-ant/src/main/java/com/carrotsearch/ant/tasks/junit4package com.carrotsearch.ant.tasks.junit4; import java.util.Collection; import java.util.List; /** * A test balancer schedules test suites to be executed on a given JVM. */ public interface SuiteBalancer { public final static class Assignment implements Comparable { /** * Test suite name. */ public final String suiteName; /** * Slave assignment. */ public final int slaveId; /** * Estimated cost; informational only (depends on the balancer). May be zero * for balancers which don't use cost at all. */ public final int estimatedCost; public Assignment(String suiteName, int slaveId, int estimatedCost) { this.suiteName = suiteName; this.slaveId = slaveId; this.estimatedCost = estimatedCost; } @Override public int compareTo(Assignment other) { int v = this.suiteName.compareTo(other.suiteName); if (v == 0) { v = this.slaveId - other.slaveId; } return v; } } /** * Sets the owner task (for logging mostly). */ void setOwner(JUnit4 owner); /** * Provide assignments for suite names and a given number of slaves. * * @return Returns an ordered list with assignments. Any suite name not present * in the keys of the returned map will be assigned by following * balancers (or randomly). */ List assign(Collection suiteNames, int slaves, long seed); } TailInputStream.java000066400000000000000000000040611235451432000355540ustar00rootroot00000000000000randomizedtesting-release-2.1.6/junit4-ant/src/main/java/com/carrotsearch/ant/tasks/junit4package com.carrotsearch.ant.tasks.junit4; import java.io.*; /** * An input stream that tails from a random access file as new input appears there. * It's a lousy solution but we don't have access to real interprocess pipes from Java. */ class TailInputStream extends InputStream { /** How long to sleep (millis) before checking for updates? */ private static final long TAIL_CHECK_DELAY = 250; private RandomAccessFile raf; private volatile boolean closed; public TailInputStream(File file) throws FileNotFoundException { this.raf = new RandomAccessFile(file, "r"); } @Override public int read() throws IOException { if (closed) return -1; try { int c; while ((c = raf.read()) == -1) { try { Thread.sleep(TAIL_CHECK_DELAY); } catch (InterruptedException e) { throw new IOException(e); } } return c; } catch (IOException e) { if (closed) return -1; else throw e; } } @Override public int read(byte[] b, int off, int len) throws IOException { if (closed) return -1; if (b == null) { throw new NullPointerException(); } else if (off < 0 || len < 0 || len > b.length - off) { throw new IndexOutOfBoundsException(); } else if (len == 0) { return 0; } try { int rafRead = raf.read(b, off, len); if (rafRead == -1) { // If nothing in the buffer, wait. do { try { Thread.sleep(TAIL_CHECK_DELAY); } catch (InterruptedException e) { throw new IOException(e); } } while ((rafRead = raf.read(b, off, len)) == -1); } return rafRead; } catch (IOException e) { if (closed) return -1; else throw e; } } @Override public int read(byte[] b) throws IOException { return read(b, 0, b.length); } @Override public boolean markSupported() { return false; } @Override public void close() throws IOException { closed = true; this.raf.close(); } } TestClass.java000066400000000000000000000003471235451432000343770ustar00rootroot00000000000000randomizedtesting-release-2.1.6/junit4-ant/src/main/java/com/carrotsearch/ant/tasks/junit4package com.carrotsearch.ant.tasks.junit4; final class TestClass { String className; boolean replicate; public TestClass() { this(null); } public TestClass(String className) { this.className = className; } } TestsCollection.java000066400000000000000000000014441235451432000356070ustar00rootroot00000000000000randomizedtesting-release-2.1.6/junit4-ant/src/main/java/com/carrotsearch/ant/tasks/junit4package com.carrotsearch.ant.tasks.junit4; import java.util.List; import java.util.Map; import com.google.common.collect.Lists; import com.google.common.collect.Maps; /** * A collection of test suites and extracted annotation information. */ final class TestsCollection { List testClasses = Lists.newArrayList(); public void add(TestClass testClass) { testClasses.add(testClass); } public void onlyUniqueSuiteNames() { Map unique = Maps.newLinkedHashMap(); for (TestClass t : testClasses) { unique.put(t.className, t); } testClasses.clear(); testClasses.addAll(unique.values()); } public boolean hasReplicatedSuites() { for (TestClass t : testClasses) { if (t.replicate) return true; } return false; } } TestsSummary.java000066400000000000000000000031031235451432000351430ustar00rootroot00000000000000randomizedtesting-release-2.1.6/junit4-ant/src/main/java/com/carrotsearch/ant/tasks/junit4package com.carrotsearch.ant.tasks.junit4; import static com.carrotsearch.ant.tasks.junit4.Pluralize.*; /** * Summary of tests execution. */ public class TestsSummary { public final int suites, suiteErrors; public final int tests, failures, errors, assumptions, ignores; public TestsSummary( int suites, int suiteErrors, int tests, int failures, int errors, int assumptions, int ignores) { this.suites = suites; this.suiteErrors = suiteErrors; this.tests = tests; this.failures = failures; this.errors = errors; this.assumptions = assumptions; this.ignores = ignores; } public boolean isSuccessful() { return (errors + failures + suiteErrors) == 0; } @Override public String toString() { StringBuilder s = new StringBuilder(); s.append(suites).append(pluralize(suites, " suite")); s.append(", ").append(tests).append(pluralize(tests, " test")); if (suiteErrors > 0) s.append(", ").append(suiteErrors).append(pluralize(suiteErrors, " suite-level error")); if (errors > 0) s.append(", ").append(errors).append(pluralize(errors, " error")); if (failures > 0) s.append(", ").append(failures).append(pluralize(failures, " failure")); if (ignores + assumptions > 0) { s.append(", ").append(ignores + assumptions).append(" ignored"); if (assumptions > 0) { s.append(" (").append(assumptions).append(pluralize(assumptions, " assumption")).append(")"); } } return s.toString(); } public int getNonIgnoredTestsCount() { return tests - (ignores + assumptions); } } TestsSummaryEventListener.java000066400000000000000000000026541235451432000376650ustar00rootroot00000000000000randomizedtesting-release-2.1.6/junit4-ant/src/main/java/com/carrotsearch/ant/tasks/junit4package com.carrotsearch.ant.tasks.junit4; import com.carrotsearch.ant.tasks.junit4.events.aggregated.AggregatedSuiteResultEvent; import com.carrotsearch.ant.tasks.junit4.events.aggregated.AggregatedTestResultEvent; import com.google.common.eventbus.EventBus; import com.google.common.eventbus.Subscribe; /** * Create a summary of tests execution. * * @see EventBus */ public class TestsSummaryEventListener { private int failures; private int tests; private int errors; private int assumptions; private int ignores; private int suites; private int suiteErrors; /** * React to suite summaries only. */ @Subscribe public void suiteSummary(AggregatedSuiteResultEvent e) { suites++; if (!e.getFailures().isEmpty()) { suiteErrors += e.getFailures().size(); } for (AggregatedTestResultEvent testResult : e.getTests()) { tests++; switch (testResult.getStatus()) { case ERROR: errors++; break; case FAILURE: failures++; break; case IGNORED: ignores++; break; case IGNORED_ASSUMPTION: assumptions++; break; default: break; } } } /** * Return the summary of all tests. */ public TestsSummary getResult() { return new TestsSummary(suites, suiteErrors, tests, failures, errors, assumptions, ignores); } } 000077500000000000000000000000001235451432000335555ustar00rootroot00000000000000randomizedtesting-release-2.1.6/junit4-ant/src/main/java/com/carrotsearch/ant/tasks/junit4/balancersExecutionTimeBalancer.java000066400000000000000000000104341235451432000406340ustar00rootroot00000000000000randomizedtesting-release-2.1.6/junit4-ant/src/main/java/com/carrotsearch/ant/tasks/junit4/balancerspackage com.carrotsearch.ant.tasks.junit4.balancers; import java.util.*; import org.apache.tools.ant.Project; import org.apache.tools.ant.ProjectComponent; import org.apache.tools.ant.types.FileSet; import org.apache.tools.ant.types.ResourceCollection; import com.carrotsearch.ant.tasks.junit4.*; import com.carrotsearch.ant.tasks.junit4.listeners.ExecutionTimesReport; import com.google.common.collect.Lists; /** * A test suite balancer based on past execution times saved using * {@link ExecutionTimesReport}. */ public class ExecutionTimeBalancer extends ProjectComponent implements SuiteBalancer { private static class SlaveLoad { public static final Comparator ASCENDING_BY_ESTIMATED_FINISH = new Comparator() { @Override public int compare(SlaveLoad o1, SlaveLoad o2) { if (o1.estimatedFinish < o2.estimatedFinish) { return -1; } else if (o1.estimatedFinish == o2.estimatedFinish) { return o1.id - o2.id; // Assume no overflows. } else { return 1; } } }; public final int id; public long estimatedFinish; public SlaveLoad(int id) { this.id = id; } } /** * All included execution time dumps. */ private List resources = Lists.newArrayList(); /** Owning task (logging). */ private JUnit4 owner; /** @see #setVerbose(boolean) */ private boolean verbose; /** * Be verbose about estimated times etc. */ public void setVerbose(boolean verbose) { this.verbose = verbose; } /** * Adds a resource collection with execution hints. */ public void add(ResourceCollection rc) { if (rc instanceof FileSet) { FileSet fs = (FileSet) rc; fs.setProject(getProject()); } resources.add(rc); } /** * Assign based on execution time history. The algorithm is a greedy heuristic * assigning the longest remaining test to the slave with the * shortest-completion time so far. This is not optimal but fast and provides * a decent average assignment. */ @Override public List assign(Collection suiteNames, int slaves, long seed) { // Read hints first. final Map> hints = ExecutionTimesReport.mergeHints(resources, suiteNames); // Preprocess and sort costs. Take the median for each suite's measurements as the // weight to avoid extreme measurements from screwing up the average. final List costs = Lists.newArrayList(); for (String suiteName : suiteNames) { final List suiteHint = hints.get(suiteName); if (suiteHint != null) { // Take the median for each suite's measurements as the weight // to avoid extreme measurements from screwing up the average. Collections.sort(suiteHint); final Long median = suiteHint.get(suiteHint.size() / 2); costs.add(new SuiteHint(suiteName, median)); } } Collections.sort(costs, SuiteHint.DESCENDING_BY_WEIGHT); // Apply the assignment heuristic. final PriorityQueue pq = new PriorityQueue( slaves, SlaveLoad.ASCENDING_BY_ESTIMATED_FINISH); for (int i = 0; i < slaves; i++) { pq.add(new SlaveLoad(i)); } final List assignments = Lists.newArrayList(); for (SuiteHint hint : costs) { SlaveLoad slave = pq.remove(); slave.estimatedFinish += hint.cost; pq.add(slave); owner.log("Expected execution time for " + hint.suiteName + ": " + Duration.toHumanDuration(hint.cost), Project.MSG_DEBUG); assignments.add(new Assignment(hint.suiteName, slave.id, (int) hint.cost)); } // Dump estimated execution times. TreeMap ordered = new TreeMap(); while (!pq.isEmpty()) { SlaveLoad slave = pq.remove(); ordered.put(slave.id, slave); } for (Integer id : ordered.keySet()) { final SlaveLoad slave = ordered.get(id); owner.log(String.format(Locale.ENGLISH, "Expected execution time on JVM J%d: %8.2fs", slave.id, slave.estimatedFinish / 1000.0f), verbose ? Project.MSG_INFO : Project.MSG_DEBUG); } return assignments; } @Override public void setOwner(JUnit4 owner) { this.owner = owner; } } MergeHints.java000066400000000000000000000040451235451432000364700ustar00rootroot00000000000000randomizedtesting-release-2.1.6/junit4-ant/src/main/java/com/carrotsearch/ant/tasks/junit4/balancerspackage com.carrotsearch.ant.tasks.junit4.balancers; import java.io.File; import java.io.IOException; import java.util.List; import java.util.Map; import org.apache.tools.ant.BuildException; import org.apache.tools.ant.Task; import org.apache.tools.ant.types.FileSet; import org.apache.tools.ant.types.ResourceCollection; import com.carrotsearch.ant.tasks.junit4.listeners.ExecutionTimesReport; import com.google.common.collect.Lists; /** * Merge execution hints emitted by {@link ExecutionTimeBalancer} to one file. */ public class MergeHints extends Task { /** * All included execution time dumps. */ private List resources = Lists.newArrayList(); /** * @see ExecutionTimesReport#setHistoryLength(int) */ private int historyLength = ExecutionTimesReport.DEFAULT_HISTORY_LENGTH; /** * Output file for merged hints. */ private File file; /** * @see ExecutionTimesReport#setHistoryLength(int) */ public void setHistoryLength(int historyLength) { if (historyLength < 0) { throw new BuildException("History length must be >= 1: " + historyLength); } this.historyLength = historyLength; } /** * Set the output file for merged hints. */ public void setFile(File file) { this.file = file; } /** * Adds a resource collection with execution hints. */ public void add(ResourceCollection rc) { if (rc instanceof FileSet) { FileSet fs = (FileSet) rc; fs.setProject(getProject()); } resources.add(rc); } @Override public void execute() throws BuildException { // Read hints first, preserve all hints. final Map> hints = ExecutionTimesReport.mergeHints( resources, /* keep all */ null); for (List hintList : hints.values()) { while (hintList.size() > historyLength) { hintList.remove(0); } } try { ExecutionTimesReport.writeHints(file, hints); } catch (IOException e) { throw new BuildException("Could not write updated hints file: " + file, e); } } } RoundRobinBalancer.java000066400000000000000000000013661235451432000401370ustar00rootroot00000000000000randomizedtesting-release-2.1.6/junit4-ant/src/main/java/com/carrotsearch/ant/tasks/junit4/balancerspackage com.carrotsearch.ant.tasks.junit4.balancers; import java.util.Collection; import java.util.List; import com.carrotsearch.ant.tasks.junit4.JUnit4; import com.carrotsearch.ant.tasks.junit4.SuiteBalancer; import com.google.common.collect.Lists; /** * A round-robin suite balancer (default for non-assigned suites). */ public class RoundRobinBalancer implements SuiteBalancer { @Override public List assign(Collection suiteNames, int slaves, long seed) { List result = Lists.newArrayList(); int i = 0; for (String suite : suiteNames) { result.add(new Assignment(suite, i++, 0)); if (i >= slaves) i = 0; } return result; } @Override public void setOwner(JUnit4 owner) {} } SuiteHint.java000066400000000000000000000012301235451432000363300ustar00rootroot00000000000000randomizedtesting-release-2.1.6/junit4-ant/src/main/java/com/carrotsearch/ant/tasks/junit4/balancerspackage com.carrotsearch.ant.tasks.junit4.balancers; import java.util.Comparator; /** * A suite with the cost hint. */ public final class SuiteHint { public static final Comparator DESCENDING_BY_WEIGHT = new Comparator() { @Override public int compare(SuiteHint o1, SuiteHint o2) { if (o1.cost == o2.cost) return o1.suiteName.compareTo(o2.suiteName); if (o1.cost < o2.cost) return 1; else return -1; } }; public final String suiteName; public final long cost; public SuiteHint(String suiteName, long weight) { this.suiteName = suiteName; this.cost = weight; } }TopHints.java000066400000000000000000000047301235451432000361740ustar00rootroot00000000000000randomizedtesting-release-2.1.6/junit4-ant/src/main/java/com/carrotsearch/ant/tasks/junit4/balancerspackage com.carrotsearch.ant.tasks.junit4.balancers; import java.util.ArrayList; import java.util.Collections; import java.util.Comparator; import java.util.List; import java.util.Locale; import java.util.Map; import org.apache.tools.ant.BuildException; import org.apache.tools.ant.Task; import org.apache.tools.ant.types.FileSet; import org.apache.tools.ant.types.ResourceCollection; import com.carrotsearch.ant.tasks.junit4.listeners.ExecutionTimesReport; import com.google.common.collect.Lists; /** * Display the slowest test suites based on hints files. */ public class TopHints extends Task { private static class Entry { String suiteName; double averageHint; public Entry(String s, double h) { this.suiteName = s; this.averageHint = h; } } private static final Comparator byDescHint = new Comparator() { @Override public int compare(Entry o1, Entry o2) { if (o1.averageHint < o2.averageHint) return 1; if (o1.averageHint > o2.averageHint) return -1; return o1.suiteName.compareTo(o2.suiteName); } }; /** * All included execution time dumps. */ private List resources = Lists.newArrayList(); /** * Max entries to display. */ private int max = 10; /** * The number of entries to display, maximum. */ public void setMax(int maxEntries) { this.max = maxEntries; } /** * Adds a resource collection with execution hints. */ public void add(ResourceCollection rc) { if (rc instanceof FileSet) { FileSet fs = (FileSet) rc; fs.setProject(getProject()); } resources.add(rc); } @Override public void execute() throws BuildException { // Read hints first, preserve all hints. final Map> hints = ExecutionTimesReport.mergeHints( resources, /* keep all */ null); // Could be done with a pq without sorting everything... ArrayList entries = new ArrayList(); for (Map.Entry> e : hints.entrySet()) { double average = 0; for (Long v : e.getValue()) { average += v; } entries.add(new Entry(e.getKey(), average / e.getValue().size())); } Collections.sort(entries, byDescHint); final int j = Math.min(max, entries.size()); for (int i = 0; i < j; i++) { log(String.format(Locale.ENGLISH, "%6.2fs | %s", entries.get(i).averageHint / 1000.0, entries.get(i).suiteName)); } } } randomizedtesting-release-2.1.6/junit4-ant/src/main/java/com/carrotsearch/ant/tasks/junit4/events/000077500000000000000000000000001235451432000332065ustar00rootroot00000000000000AbstractEvent.java000066400000000000000000000010221235451432000365320ustar00rootroot00000000000000randomizedtesting-release-2.1.6/junit4-ant/src/main/java/com/carrotsearch/ant/tasks/junit4/eventspackage com.carrotsearch.ant.tasks.junit4.events; /** * An abstract {@link IEvent}. */ abstract class AbstractEvent implements IEvent { /** Type is recreated in constructors anyway. */ private transient final EventType type; public AbstractEvent(EventType type) { if (this.getClass() != type.eventClass) { throw new RuntimeException("Event type mismatch: " + type + ", class: " + this.getClass()); } this.type = type; } @Override public EventType getType() { return type; } } AbstractEventWithDescription.java000066400000000000000000000010621235451432000415760ustar00rootroot00000000000000randomizedtesting-release-2.1.6/junit4-ant/src/main/java/com/carrotsearch/ant/tasks/junit4/eventspackage com.carrotsearch.ant.tasks.junit4.events; import org.junit.runner.Description; abstract class AbstractEventWithDescription extends AbstractEvent implements IDescribable { private Description description; public AbstractEventWithDescription(EventType type) { super(type); } public Description getDescription() { return description; } protected void setDescription(Description description) { if (this.description != null) throw new IllegalStateException("Initialize once."); this.description = description; } } AppendStdErrEvent.java000066400000000000000000000010241235451432000373240ustar00rootroot00000000000000randomizedtesting-release-2.1.6/junit4-ant/src/main/java/com/carrotsearch/ant/tasks/junit4/eventspackage com.carrotsearch.ant.tasks.junit4.events; import java.io.IOException; import java.io.OutputStream; public class AppendStdErrEvent extends AbstractEvent implements IStreamEvent { private byte[] chunk; protected AppendStdErrEvent() { super(EventType.APPEND_STDERR); } public AppendStdErrEvent(byte[] b, int off, int len) { this(); chunk = new byte [len]; System.arraycopy(b, off, chunk, 0, len); } @Override public void copyTo(OutputStream os) throws IOException { os.write(chunk); } }AppendStdOutEvent.java000066400000000000000000000010251235451432000373440ustar00rootroot00000000000000randomizedtesting-release-2.1.6/junit4-ant/src/main/java/com/carrotsearch/ant/tasks/junit4/eventspackage com.carrotsearch.ant.tasks.junit4.events; import java.io.IOException; import java.io.OutputStream; public class AppendStdOutEvent extends AbstractEvent implements IStreamEvent { private byte[] chunk; protected AppendStdOutEvent() { super(EventType.APPEND_STDOUT); } public AppendStdOutEvent(byte[] b, int off, int len) { this(); chunk = new byte [len]; System.arraycopy(b, off, chunk, 0, len); } @Override public void copyTo(OutputStream os) throws IOException { os.write(chunk); } } BootstrapEvent.java000066400000000000000000000035151235451432000367550ustar00rootroot00000000000000randomizedtesting-release-2.1.6/junit4-ant/src/main/java/com/carrotsearch/ant/tasks/junit4/eventspackage com.carrotsearch.ant.tasks.junit4.events; import java.lang.management.ManagementFactory; import java.nio.charset.Charset; import java.util.Map; import java.util.TreeMap; /** * Initial message sent from the slave to the master (if forked locally). */ public class BootstrapEvent extends AbstractEvent { private String defaultCharset; private Map systemProperties; private String pidString; /** Preinitialization with local machine's configuration. */ public BootstrapEvent() { super(EventType.BOOTSTRAP); this.defaultCharset = Charset.defaultCharset().name(); try { pidString = ManagementFactory.getRuntimeMXBean().getName(); } catch (Throwable t) { pidString = ""; } this.systemProperties = new TreeMap(); for (Map.Entry e : System.getProperties().entrySet()) { Object key = e.getKey(); Object value = e.getValue(); if (key != null) { systemProperties.put( key.toString(), value != null ? value.toString() : ""); } } systemProperties.put("junit4.memory.total", Long.toString(Runtime.getRuntime().totalMemory())); systemProperties.put("junit4.processors", Long.toString(Runtime.getRuntime().availableProcessors())); systemProperties.put("junit4.pidString", pidString); } /** * Default charset on the slave. */ public String getDefaultCharsetName() { return defaultCharset; } /** * System properties on the slave. */ public Map getSystemProperties() { return systemProperties; } /** * Returns a PID string or anything that approximates it and would * help in dumping a stack trace externally, for example. */ public String getPidString() { return pidString; } } Deserializer.java000066400000000000000000000015741235451432000364230ustar00rootroot00000000000000randomizedtesting-release-2.1.6/junit4-ant/src/main/java/com/carrotsearch/ant/tasks/junit4/eventspackage com.carrotsearch.ant.tasks.junit4.events; import java.io.*; import com.google.common.base.Charsets; import com.google.gson.*; import com.google.gson.stream.JsonReader; import com.google.gson.stream.JsonToken; /** * Event deserializer. */ public class Deserializer { private JsonReader input; private Gson gson; public Deserializer(InputStream is, ClassLoader refLoader) throws IOException { input = new JsonReader(new InputStreamReader(is, Charsets.UTF_8)); input.setLenient(true); gson = Serializer.createGSon(refLoader); } public IEvent deserialize() throws IOException { JsonToken peek = input.peek(); if (peek == JsonToken.END_ARRAY) return null; input.beginArray(); EventType type = EventType.valueOf(input.nextString()); IEvent event = gson.fromJson(input, type.eventClass); input.endArray(); return event; } } EventType.java000066400000000000000000000016631235451432000357230ustar00rootroot00000000000000randomizedtesting-release-2.1.6/junit4-ant/src/main/java/com/carrotsearch/ant/tasks/junit4/eventspackage com.carrotsearch.ant.tasks.junit4.events; /** * Events (messages) passed between the slave and the master. */ public enum EventType { BOOTSTRAP(BootstrapEvent.class), SUITE_STARTED(SuiteStartedEvent.class), SUITE_FAILURE(SuiteFailureEvent.class), SUITE_COMPLETED(SuiteCompletedEvent.class), APPEND_STDOUT(AppendStdOutEvent.class), APPEND_STDERR(AppendStdErrEvent.class), TEST_STARTED(TestStartedEvent.class), TEST_FAILURE(TestFailureEvent.class), TEST_IGNORED_ASSUMPTION(TestIgnoredAssumptionEvent.class), TEST_IGNORED(TestIgnoredEvent.class), TEST_FINISHED(TestFinishedEvent.class), IDLE(IdleEvent.class), QUIT(QuitEvent.class); /** * Concrete class associated with the given event type. */ public final Class eventClass; /** * Initialize with concrete event class. */ private EventType(Class eventClass) { this.eventClass = eventClass; } } FailureEvent.java000066400000000000000000000014061235451432000363640ustar00rootroot00000000000000randomizedtesting-release-2.1.6/junit4-ant/src/main/java/com/carrotsearch/ant/tasks/junit4/eventspackage com.carrotsearch.ant.tasks.junit4.events; import org.junit.runner.Description; import org.junit.runner.notification.Failure; import com.carrotsearch.ant.tasks.junit4.events.mirrors.FailureMirror; /** * Generic serialized failure event. */ public abstract class FailureEvent extends AbstractEvent implements IDescribable { private FailureMirror failure; public FailureEvent(EventType type) { super(type); } protected void setFailure(Failure failure) { if (this.failure != null) { throw new IllegalStateException("Set only once."); } this.failure = new FailureMirror(failure); } public FailureMirror getFailure() { return failure; } public Description getDescription() { return failure.getDescription(); } } IDescribable.java000066400000000000000000000003231235451432000363000ustar00rootroot00000000000000randomizedtesting-release-2.1.6/junit4-ant/src/main/java/com/carrotsearch/ant/tasks/junit4/eventspackage com.carrotsearch.ant.tasks.junit4.events; import org.junit.runner.Description; /** * An event that carries a {@link Description}. */ public interface IDescribable { Description getDescription(); } IEvent.java000066400000000000000000000002551235451432000351660ustar00rootroot00000000000000randomizedtesting-release-2.1.6/junit4-ant/src/main/java/com/carrotsearch/ant/tasks/junit4/eventspackage com.carrotsearch.ant.tasks.junit4.events; /** * An event/ message passed between the slave and the master. */ public interface IEvent { EventType getType(); } IStreamEvent.java000066400000000000000000000003111235451432000363330ustar00rootroot00000000000000randomizedtesting-release-2.1.6/junit4-ant/src/main/java/com/carrotsearch/ant/tasks/junit4/eventspackage com.carrotsearch.ant.tasks.junit4.events; import java.io.IOException; import java.io.OutputStream; public interface IStreamEvent { public void copyTo(OutputStream os) throws IOException; } IdleEvent.java000066400000000000000000000003421235451432000356500ustar00rootroot00000000000000randomizedtesting-release-2.1.6/junit4-ant/src/main/java/com/carrotsearch/ant/tasks/junit4/eventspackage com.carrotsearch.ant.tasks.junit4.events; /** * Marker that the slave is idle and awaiting more suite names. */ public class IdleEvent extends AbstractEvent { public IdleEvent() { super(EventType.IDLE); } } LowLevelHeartBeatEvent.java000066400000000000000000000005111235451432000403020ustar00rootroot00000000000000randomizedtesting-release-2.1.6/junit4-ant/src/main/java/com/carrotsearch/ant/tasks/junit4/eventspackage com.carrotsearch.ant.tasks.junit4.events; /** * Heartbeat for reporting long running tests. */ public class LowLevelHeartBeatEvent { public final long lastActivity, currentTime; public LowLevelHeartBeatEvent(long last, long currentTime) { this.lastActivity = last; this.currentTime = currentTime; } } QuitEvent.java000066400000000000000000000003471235451432000357220ustar00rootroot00000000000000randomizedtesting-release-2.1.6/junit4-ant/src/main/java/com/carrotsearch/ant/tasks/junit4/eventspackage com.carrotsearch.ant.tasks.junit4.events; /** * Final message sent from the slave. Also signals orderly shutdown. */ public class QuitEvent extends AbstractEvent { public QuitEvent() { super(EventType.QUIT); } } Serializer.java000066400000000000000000000102111235451432000360760ustar00rootroot00000000000000randomizedtesting-release-2.1.6/junit4-ant/src/main/java/com/carrotsearch/ant/tasks/junit4/eventspackage com.carrotsearch.ant.tasks.junit4.events; import java.io.*; import java.lang.annotation.Annotation; import java.util.ArrayDeque; import org.junit.runner.Description; import com.carrotsearch.ant.tasks.junit4.events.json.*; import com.carrotsearch.ant.tasks.junit4.slave.SlaveMain; import com.google.common.base.Charsets; import com.google.gson.Gson; import com.google.gson.GsonBuilder; import com.google.gson.LongSerializationPolicy; import com.google.gson.stream.JsonWriter; /** * Event serializer. */ public class Serializer implements Closeable { /** * Should help in ensuring the right order of stream writes. */ private final Object lock = new Object(); private Writer writer; private Gson gson; private final ArrayDeque events = new ArrayDeque(); private volatile Throwable doForcedShutdown; private Thread forceCloseDaemon; public Serializer(OutputStream os) throws IOException { this.writer = new OutputStreamWriter(os, Charsets.UTF_8); this.gson = createGSon(Thread.currentThread().getContextClassLoader()); this.forceCloseDaemon = new Thread("JUnit4-serializer-daemon") { { this.setDaemon(true); } @Override public void run() { try { while (true) { Thread.sleep(1000); Throwable reason = doForcedShutdown; if (reason != null) { try { SlaveMain.warn("Unhandled exception in event serialization.", reason); } finally { Runtime.getRuntime().halt(0); } } } } catch (InterruptedException e) { // Ignore and exit. } } }; forceCloseDaemon.start(); } public Serializer serialize(IEvent event) throws IOException { synchronized (lock) { if (writer == null) { throw new IOException("Serializer already closed."); } do { // An alternative way of solving GH-92 and GH-110. Instead of buffering // serialized json we emit directly. If a recursive call occurs to serialize() // we enqueue the event and continue, serializing them in order. events.addLast(event); if (events.size() > 1) { return this; } event = events.peekFirst(); try { JsonWriter jsonWriter = new JsonWriter(writer); jsonWriter.setIndent(" "); jsonWriter.beginArray(); jsonWriter.value(event.getType().name()); gson.toJson(event, event.getClass(), jsonWriter); jsonWriter.endArray(); writer.write("\n\n"); } catch (Throwable t) { // We can't do a stack bang here so any call is a risk of hitting SOE again. while (true) { doForcedShutdown = t; try { forceCloseDaemon.join(); } catch (Throwable ignored) { // Ignore. } } } events.removeFirst(); } while (writer != null && !events.isEmpty()); return this; } } public Serializer flush() throws IOException { synchronized (lock) { if (writer != null) { writer.flush(); } return this; } } public void close() throws IOException { synchronized (lock) { if (writer != null) { if (events.isEmpty()) { serialize(new QuitEvent()); } writer.close(); writer = null; } try { forceCloseDaemon.interrupt(); forceCloseDaemon.join(); } catch (InterruptedException e) { // Ignore, can't do much about it (shouldn't happen). } } } public static Gson createGSon(ClassLoader refLoader) { return new GsonBuilder() .registerTypeAdapter(byte[].class, new JsonByteArrayAdapter()) .registerTypeHierarchyAdapter(Annotation.class, new JsonAnnotationAdapter(refLoader)) .registerTypeHierarchyAdapter(Class.class, new JsonClassAdapter(refLoader)) .registerTypeAdapter(Description.class, new JsonDescriptionAdapter()) .setLongSerializationPolicy(LongSerializationPolicy.DEFAULT) .disableHtmlEscaping() .create(); } }SuiteCompletedEvent.java000066400000000000000000000012361235451432000377240ustar00rootroot00000000000000randomizedtesting-release-2.1.6/junit4-ant/src/main/java/com/carrotsearch/ant/tasks/junit4/eventspackage com.carrotsearch.ant.tasks.junit4.events; import org.junit.runner.Description; /** * Serialized failure. */ public class SuiteCompletedEvent extends AbstractEventWithDescription { private long startTimestamp; private long executionTime; protected SuiteCompletedEvent() { super(EventType.SUITE_COMPLETED); } public SuiteCompletedEvent(Description description, long start, long duration) { this(); this.startTimestamp = start; this.executionTime = duration; setDescription(description); } public long getExecutionTime() { return executionTime; } public long getStartTimestamp() { return startTimestamp; } } SuiteFailureEvent.java000066400000000000000000000005341235451432000373770ustar00rootroot00000000000000randomizedtesting-release-2.1.6/junit4-ant/src/main/java/com/carrotsearch/ant/tasks/junit4/eventspackage com.carrotsearch.ant.tasks.junit4.events; import org.junit.runner.notification.Failure; /** * Serialized failure. */ public class SuiteFailureEvent extends FailureEvent { protected SuiteFailureEvent() { super(EventType.SUITE_FAILURE); } public SuiteFailureEvent(Failure failure) { this(); setFailure(failure); } } SuiteStartedEvent.java000066400000000000000000000010271235451432000374140ustar00rootroot00000000000000randomizedtesting-release-2.1.6/junit4-ant/src/main/java/com/carrotsearch/ant/tasks/junit4/eventspackage com.carrotsearch.ant.tasks.junit4.events; import org.junit.runner.Description; /** * Serialized failure. */ public class SuiteStartedEvent extends AbstractEventWithDescription { private long startTimestamp; protected SuiteStartedEvent() { super(EventType.SUITE_STARTED); } public SuiteStartedEvent(Description description, long startTimestamp) { this(); setDescription(description); this.startTimestamp = startTimestamp; } public long getStartTimestamp() { return startTimestamp; } }TestFailureEvent.java000066400000000000000000000004701235451432000372240ustar00rootroot00000000000000randomizedtesting-release-2.1.6/junit4-ant/src/main/java/com/carrotsearch/ant/tasks/junit4/eventspackage com.carrotsearch.ant.tasks.junit4.events; import org.junit.runner.notification.Failure; public class TestFailureEvent extends FailureEvent { protected TestFailureEvent() { super(EventType.TEST_FAILURE); } public TestFailureEvent(Failure failure) { this(); setFailure(failure); } } TestFinishedEvent.java000066400000000000000000000012121235451432000373610ustar00rootroot00000000000000randomizedtesting-release-2.1.6/junit4-ant/src/main/java/com/carrotsearch/ant/tasks/junit4/eventspackage com.carrotsearch.ant.tasks.junit4.events; import org.junit.runner.Description; public class TestFinishedEvent extends AbstractEventWithDescription { private int executionTime; private long startTimestamp; protected TestFinishedEvent() { super(EventType.TEST_FINISHED); } public TestFinishedEvent(Description description, int timeMillis, long startTimestamp) { this(); this.executionTime = timeMillis; this.startTimestamp = startTimestamp; setDescription(description); } public int getExecutionTime() { return executionTime; } public long getStartTimestamp() { return startTimestamp; } } TestIgnoredAssumptionEvent.java000066400000000000000000000005411235451432000413060ustar00rootroot00000000000000randomizedtesting-release-2.1.6/junit4-ant/src/main/java/com/carrotsearch/ant/tasks/junit4/eventspackage com.carrotsearch.ant.tasks.junit4.events; import org.junit.runner.notification.Failure; public class TestIgnoredAssumptionEvent extends FailureEvent { protected TestIgnoredAssumptionEvent() { super(EventType.TEST_IGNORED_ASSUMPTION); } public TestIgnoredAssumptionEvent(Failure failure) { this(); setFailure(failure); } } TestIgnoredEvent.java000066400000000000000000000012521235451432000372230ustar00rootroot00000000000000randomizedtesting-release-2.1.6/junit4-ant/src/main/java/com/carrotsearch/ant/tasks/junit4/eventspackage com.carrotsearch.ant.tasks.junit4.events; import org.junit.runner.Description; public class TestIgnoredEvent extends AbstractEventWithDescription { private long startTimestamp; private String cause; protected TestIgnoredEvent() { super(EventType.TEST_IGNORED); } public TestIgnoredEvent(Description description, String cause) { this(); setDescription(description); // For ignored tests, take the current time as the execution timestamp. this.startTimestamp = System.currentTimeMillis(); this.cause = cause; } public long getStartTimestamp() { return startTimestamp; } public String getCause() { return cause; } } TestStartedEvent.java000066400000000000000000000005171235451432000372450ustar00rootroot00000000000000randomizedtesting-release-2.1.6/junit4-ant/src/main/java/com/carrotsearch/ant/tasks/junit4/eventspackage com.carrotsearch.ant.tasks.junit4.events; import org.junit.runner.Description; public class TestStartedEvent extends AbstractEventWithDescription { protected TestStartedEvent() { super(EventType.TEST_STARTED); } public TestStartedEvent(Description description) { this(); setDescription(description); } } 000077500000000000000000000000001235451432000352215ustar00rootroot00000000000000randomizedtesting-release-2.1.6/junit4-ant/src/main/java/com/carrotsearch/ant/tasks/junit4/events/aggregatedAggregatedQuitEvent.java000066400000000000000000000002571235451432000417670ustar00rootroot00000000000000randomizedtesting-release-2.1.6/junit4-ant/src/main/java/com/carrotsearch/ant/tasks/junit4/events/aggregatedpackage com.carrotsearch.ant.tasks.junit4.events.aggregated; /** * An event dispatched after all slaves have completed their jobs. */ public class AggregatedQuitEvent { } AggregatedResultEvent.java000066400000000000000000000012241235451432000423160ustar00rootroot00000000000000randomizedtesting-release-2.1.6/junit4-ant/src/main/java/com/carrotsearch/ant/tasks/junit4/events/aggregatedpackage com.carrotsearch.ant.tasks.junit4.events.aggregated; import java.util.List; import org.junit.runner.Description; import com.carrotsearch.ant.tasks.junit4.ForkedJvmInfo; import com.carrotsearch.ant.tasks.junit4.events.IEvent; import com.carrotsearch.ant.tasks.junit4.events.mirrors.FailureMirror; /** * Aggregated result from a suite or test. */ public interface AggregatedResultEvent { public Description getDescription(); public ForkedJvmInfo getSlave(); public boolean isSuccessful(); public List getFailures(); List getEventStream(); public long getStartTimestamp(); public long getExecutionTime(); } AggregatedStartEvent.java000066400000000000000000000010311235451432000421310ustar00rootroot00000000000000randomizedtesting-release-2.1.6/junit4-ant/src/main/java/com/carrotsearch/ant/tasks/junit4/events/aggregatedpackage com.carrotsearch.ant.tasks.junit4.events.aggregated; /** * An event dispatched before any slave starts. */ public class AggregatedStartEvent { private int slaves; private int suiteCount; public AggregatedStartEvent(int slaves, int suiteCount) { this.slaves = slaves; this.suiteCount = suiteCount; } /** * Number of slave processes. */ public int getSlaveCount() { return slaves; } /** * Number of test suites, total. */ public int getSuiteCount() { return suiteCount; } } AggregatedSuiteResultEvent.java000066400000000000000000000063541235451432000433410ustar00rootroot00000000000000randomizedtesting-release-2.1.6/junit4-ant/src/main/java/com/carrotsearch/ant/tasks/junit4/events/aggregatedpackage com.carrotsearch.ant.tasks.junit4.events.aggregated; import java.util.Collections; import java.util.List; import org.junit.runner.Description; import com.carrotsearch.ant.tasks.junit4.ForkedJvmInfo; import com.carrotsearch.ant.tasks.junit4.events.IEvent; import com.carrotsearch.ant.tasks.junit4.events.mirrors.FailureMirror; public class AggregatedSuiteResultEvent implements AggregatedResultEvent { private transient final ForkedJvmInfo slave; private final long executionTime; private final long startTimestamp; private final Description description; private final List tests; private final List suiteFailures; private final List eventStream; public AggregatedSuiteResultEvent(ForkedJvmInfo id, Description description, List suiteFailures, List tests, List eventStream, long startTimestamp, long executionTime) { this.slave = id; this.tests = tests; this.suiteFailures = suiteFailures; this.description = description; this.eventStream = eventStream; this.executionTime = executionTime; this.startTimestamp = startTimestamp; } public List getTests() { return tests; } @Override public List getFailures() { return Collections.unmodifiableList(suiteFailures); } @Override public boolean isSuccessful() { if (!suiteFailures.isEmpty()) return false; for (AggregatedTestResultEvent e : tests) { if (!e.isSuccessful()) { return false; } } return true; } @Override public List getEventStream() { return eventStream; } @Override public ForkedJvmInfo getSlave() { return slave; } @Override public Description getDescription() { return description; } /** * Execution time in milliseconds. */ public long getExecutionTime() { return executionTime; } /** * Execution start timestamp (on the slave). */ public long getStartTimestamp() { return startTimestamp; } /** * The number of tests that have {@link TestStatus#FAILURE} and * include assertion violations at suite level. */ public int getFailureCount() { int count = 0; for (AggregatedTestResultEvent t : getTests()) { if (t.getStatus() == TestStatus.FAILURE) count++; } for (FailureMirror m : getFailures()) { if (m.isAssertionViolation()) count++; } return count; } /** * The number of tests that have {@link TestStatus#ERROR} and * include the suite-level errors. */ public int getErrorCount() { int count = 0; for (AggregatedTestResultEvent t : getTests()) { if (t.getStatus() == TestStatus.ERROR) count++; } for (FailureMirror m : getFailures()) { if (m.isErrorViolation()) count++; } return count; } /** * Return the number of ignored or assumption-ignored tests. */ public int getIgnoredCount() { int count = 0; for (AggregatedTestResultEvent t : getTests()) { if (t.getStatus() == TestStatus.IGNORED || t.getStatus() == TestStatus.IGNORED_ASSUMPTION) { count++; } } return count; } } AggregatedSuiteStartedEvent.java000066400000000000000000000011431235451432000434600ustar00rootroot00000000000000randomizedtesting-release-2.1.6/junit4-ant/src/main/java/com/carrotsearch/ant/tasks/junit4/events/aggregatedpackage com.carrotsearch.ant.tasks.junit4.events.aggregated; import com.carrotsearch.ant.tasks.junit4.ForkedJvmInfo; import com.carrotsearch.ant.tasks.junit4.events.SuiteStartedEvent; public class AggregatedSuiteStartedEvent { private transient final ForkedJvmInfo slave; private SuiteStartedEvent suiteStartedEvent; public AggregatedSuiteStartedEvent(ForkedJvmInfo id, SuiteStartedEvent e) { this.slave = id; this.suiteStartedEvent = e; } public SuiteStartedEvent getSuiteStartedEvent() { return suiteStartedEvent; } public ForkedJvmInfo getSlave() { return slave; } } AggregatedTestResultEvent.java000066400000000000000000000070511235451432000431620ustar00rootroot00000000000000randomizedtesting-release-2.1.6/junit4-ant/src/main/java/com/carrotsearch/ant/tasks/junit4/events/aggregatedpackage com.carrotsearch.ant.tasks.junit4.events.aggregated; import java.util.Collections; import java.util.List; import org.junit.runner.Description; import com.carrotsearch.ant.tasks.junit4.ForkedJvmInfo; import com.carrotsearch.ant.tasks.junit4.events.IEvent; import com.carrotsearch.ant.tasks.junit4.events.TestFinishedEvent; import com.carrotsearch.ant.tasks.junit4.events.mirrors.FailureMirror; import com.google.common.collect.Lists; /** * A single test's execution information. */ public class AggregatedTestResultEvent implements AggregatedResultEvent { private final Description suite; private final Description description; private final ForkedJvmInfo slave; private TestStatus status = TestStatus.OK; private List failures = Lists.newArrayList(); private List eventStream; private boolean hasFailures; private boolean hasErrors; private boolean hasIgnoredAssumptions; /** If {@link #status} is {@link TestStatus#IGNORED} then this contains the cause. */ private String ignoreCause; /** Associated {@link TestFinishedEvent}. */ private TestFinishedEvent testFinishedEvent; public AggregatedTestResultEvent(ForkedJvmInfo slave, Description suiteDescription, Description description) { this.description = description; this.suite = suiteDescription; this.slave = slave; } @Override public Description getDescription() { return description; } @Override public boolean isSuccessful() { return status == TestStatus.OK || status == TestStatus.IGNORED || status == TestStatus.IGNORED_ASSUMPTION; } public Description getSuiteDescription() { return suite; } @Override public ForkedJvmInfo getSlave() { return slave; } @Override public List getFailures() { return Collections.unmodifiableList(failures); } /** * Execution time in millis. */ public long getExecutionTime() { return testFinishedEvent.getExecutionTime(); } /** * Execution start timestamp (on the slave). */ public long getStartTimestamp() { return testFinishedEvent.getStartTimestamp(); } /** * Raw {@link IEvent} stream received during the duration of this test. */ @Override public List getEventStream() { if (eventStream == null) throw new RuntimeException("Unfinished test?" + suite + ", " + description); return Collections.unmodifiableList(eventStream); } /** * Exit status for this test. */ public TestStatus getStatus() { return status; } public String getCauseForIgnored() { return ignoreCause; } void setIgnored(String cause) { assert status == TestStatus.OK; status = TestStatus.IGNORED; ignoreCause = cause; } void addFailure(FailureMirror failure) { failures.add(failure); hasFailures |= failure.isAssertionViolation(); hasIgnoredAssumptions |= failure.isAssumptionViolation(); hasErrors |= failure.isErrorViolation(); } void complete(TestFinishedEvent e, List eventStream) { this.eventStream = eventStream; this.testFinishedEvent = e; if (hasErrors) { status = TestStatus.ERROR; } else if (hasFailures) { status = TestStatus.FAILURE; } else if (hasIgnoredAssumptions) { status = TestStatus.IGNORED_ASSUMPTION; } } /** * This isn't a nice hack but it allows associating {@link TestFinishedEvent} and * {@link AggregatedTestResultEvent} by identity. = */ public TestFinishedEvent getTestFinishedEvent() { return testFinishedEvent; } } AggregatingListener.java000066400000000000000000000125031235451432000420120ustar00rootroot00000000000000randomizedtesting-release-2.1.6/junit4-ant/src/main/java/com/carrotsearch/ant/tasks/junit4/events/aggregatedpackage com.carrotsearch.ant.tasks.junit4.events.aggregated; import java.util.ArrayDeque; import java.util.ArrayList; import java.util.List; import org.junit.runner.Description; import org.junit.runner.JUnitCore; import com.carrotsearch.ant.tasks.junit4.ForkedJvmInfo; import com.carrotsearch.ant.tasks.junit4.events.*; import com.carrotsearch.ant.tasks.junit4.events.mirrors.FailureMirror; import com.google.common.collect.Lists; import com.google.common.eventbus.EventBus; import com.google.common.eventbus.Subscribe; /** * Aggregates atomic events from {@link JUnitCore} to higher-level events that * contain a full summary of a given test's execution. Simplifies reporting * logic. */ public class AggregatingListener { private EventBus target; private ForkedJvmInfo slave; private Description lastSuite; private List suiteFailures; private ArrayDeque tests; private ArrayList eventStream; private int testStartStreamMarker; /** * @param target Which event bus to repost aggregated events to? */ public AggregatingListener(EventBus target, ForkedJvmInfo slave) { this.target = target; this.slave = slave; } @Subscribe public void appendToEventStream(IEvent e) { if (eventStream != null) { switch (e.getType()) { case APPEND_STDOUT: case APPEND_STDERR: target.post(new PartialOutputEvent(slave, e)); // fall through. case TEST_STARTED: case TEST_FINISHED: case TEST_FAILURE: case TEST_IGNORED: case TEST_IGNORED_ASSUMPTION: case SUITE_FAILURE: eventStream.add(e); break; default: break; } } } /** * Detect slow heartbeat (long time without any events) from the forked JVM. */ @Subscribe public void slowHeartBeat(LowLevelHeartBeatEvent e) { Description current = null; if (tests != null && !tests.isEmpty()) { current = tests.peek().getDescription(); } else { current = lastSuite; // may be null. } target.post(new HeartBeatEvent( slave, current, e.lastActivity, e.currentTime )); } @Subscribe public void receiveSuiteStart(SuiteStartedEvent e) { assert lastSuite == null; tests = new ArrayDeque(); suiteFailures = Lists.newArrayList(); eventStream = Lists.newArrayList(); lastSuite = e.getDescription(); target.post(new AggregatedSuiteStartedEvent(slave, e)); } @Subscribe public void receiveTestStart(TestStartedEvent e) { tests.push(new AggregatedTestResultEvent(slave, lastSuite, e.getDescription())); testStartStreamMarker = eventStream.size(); } @Subscribe public void receiveTestIgnored(TestIgnoredEvent e) { Description description = e.getDescription(); if (description.getMethodName() == null) { // This is how JUnit signals ignored suites: by passing a Description that is a // suite but has no children (so isSuite() returns false...). return; } // Test ignored is not emitted within start...end space with default JUnit runners. // Try to correct it here. if (!tests.isEmpty() && description.equals(tests.peek().getDescription())) { tests.peek().setIgnored(e.getCause()); } else { receiveTestStart(new TestStartedEvent(description)); tests.peek().setIgnored(e.getCause()); receiveTestEnd(new TestFinishedEvent(description, 0, e.getStartTimestamp())); } } @Subscribe public void receiveTestAssumptionIgnored(TestIgnoredAssumptionEvent e) { Description description = e.getDescription(); if (description.getMethodName() == null) { // Don't record suite-level assumptions. They result in ignored // tests that RandomizedRunner reports and JUnit runner ignores // as if a suite didn't have any tests. return; } assert e.getDescription().equals(tests.peek().getDescription()); tests.peek().addFailure(e.getFailure()); } @Subscribe public void receiveTestFailure(TestFailureEvent e) { Description description = e.getDescription(); if (description.getMethodName() == null) { suiteFailures.add(e.getFailure()); return; } tests.peek().addFailure(e.getFailure()); } @Subscribe public void receiveTestEnd(TestFinishedEvent e) { assert e.getDescription().equals(tests.peek().getDescription()); tests.peek().complete(e, Lists.newArrayList(eventStream.subList(testStartStreamMarker, eventStream.size()))); target.post(tests.peek()); } @Subscribe public void receiveSuiteEnd(SuiteCompletedEvent e) { target.post(new AggregatedSuiteResultEvent( slave, e.getDescription(), suiteFailures, Lists.newArrayList(tests.descendingIterator()), eventStream, e.getStartTimestamp(), e.getExecutionTime())); this.suiteFailures = null; this.lastSuite = null; this.tests = null; this.eventStream = null; } @Subscribe public void receiveSuiteFailure(SuiteFailureEvent e) { if (suiteFailures != null) { suiteFailures.add(e.getFailure()); } else { receiveSuiteStart(new SuiteStartedEvent(e.getDescription(), System.currentTimeMillis())); suiteFailures.add(e.getFailure()); receiveSuiteEnd(new SuiteCompletedEvent(e.getDescription(), System.currentTimeMillis(), 0)); } } } ChildBootstrap.java000066400000000000000000000005301235451432000410030ustar00rootroot00000000000000randomizedtesting-release-2.1.6/junit4-ant/src/main/java/com/carrotsearch/ant/tasks/junit4/events/aggregatedpackage com.carrotsearch.ant.tasks.junit4.events.aggregated; import com.carrotsearch.ant.tasks.junit4.ForkedJvmInfo; public class ChildBootstrap { public final ForkedJvmInfo childInfo; public ChildBootstrap(ForkedJvmInfo childInfo) { this.childInfo = childInfo; } public ForkedJvmInfo getSlave() { return childInfo; } } HeartBeatEvent.java000066400000000000000000000023101235451432000407210ustar00rootroot00000000000000randomizedtesting-release-2.1.6/junit4-ant/src/main/java/com/carrotsearch/ant/tasks/junit4/events/aggregatedpackage com.carrotsearch.ant.tasks.junit4.events.aggregated; import org.junit.runner.Description; import com.carrotsearch.ant.tasks.junit4.ForkedJvmInfo; /** * High level heartbeat event issued to report listeners when a forked JVM * does not repond for a longer while. The {@link #getDescription} method should * return an approximate place where the forked JVM is at the moment, but this is * not guaranteed (and may be null). */ public final class HeartBeatEvent { private final ForkedJvmInfo slave; private final Description description; private final long lastActivity; private final long currentTime; public HeartBeatEvent(ForkedJvmInfo slave, Description description, long lastActivity, long currentTime) { this.slave = slave; this.description = description; this.lastActivity = lastActivity; this.currentTime = currentTime; } public Description getDescription() { return description; } public long getCurrentTime() { return currentTime; } public long getLastActivity() { return lastActivity; } public long getNoEventDuration() { return getCurrentTime() - getLastActivity(); } public ForkedJvmInfo getSlave() { return slave; } } PartialOutputEvent.java000066400000000000000000000012051235451432000417010ustar00rootroot00000000000000randomizedtesting-release-2.1.6/junit4-ant/src/main/java/com/carrotsearch/ant/tasks/junit4/events/aggregatedpackage com.carrotsearch.ant.tasks.junit4.events.aggregated; import com.carrotsearch.ant.tasks.junit4.ForkedJvmInfo; import com.carrotsearch.ant.tasks.junit4.events.IEvent; import com.carrotsearch.ant.tasks.junit4.events.IStreamEvent; /** * Partial output emitted from a given slave. */ public class PartialOutputEvent { private ForkedJvmInfo slave; private IEvent event; public PartialOutputEvent(ForkedJvmInfo slave, IEvent e) { assert e instanceof IStreamEvent; this.slave = slave; this.event = e; } public ForkedJvmInfo getSlave() { return slave; } public IEvent getEvent() { return event; } } TestStatus.java000066400000000000000000000002301235451432000402020ustar00rootroot00000000000000randomizedtesting-release-2.1.6/junit4-ant/src/main/java/com/carrotsearch/ant/tasks/junit4/events/aggregatedpackage com.carrotsearch.ant.tasks.junit4.events.aggregated; public enum TestStatus { OK, IGNORED, IGNORED_ASSUMPTION, FAILURE, ERROR, } 000077500000000000000000000000001235451432000341005ustar00rootroot00000000000000randomizedtesting-release-2.1.6/junit4-ant/src/main/java/com/carrotsearch/ant/tasks/junit4/events/jsonJsonAnnotationAdapter.java000066400000000000000000000056341235451432000412200ustar00rootroot00000000000000randomizedtesting-release-2.1.6/junit4-ant/src/main/java/com/carrotsearch/ant/tasks/junit4/events/jsonpackage com.carrotsearch.ant.tasks.junit4.events.json; import java.lang.annotation.Annotation; import java.lang.reflect.InvocationHandler; import java.lang.reflect.Method; import java.lang.reflect.Proxy; import java.lang.reflect.Type; import java.util.Map; import java.util.Map.Entry; import java.util.Set; import com.google.common.collect.Maps; import com.google.gson.JsonDeserializationContext; import com.google.gson.JsonDeserializer; import com.google.gson.JsonElement; import com.google.gson.JsonObject; import com.google.gson.JsonParseException; import com.google.gson.JsonSerializationContext; import com.google.gson.JsonSerializer; public class JsonAnnotationAdapter implements JsonSerializer, JsonDeserializer { private final ClassLoader refLoader; public JsonAnnotationAdapter(ClassLoader refLoader) { this.refLoader = refLoader; } @Override public JsonElement serialize(Annotation src, Type typeOfSrc, JsonSerializationContext context) { Class annType = src.annotationType(); JsonObject ob = new JsonObject(); for (Method m : annType.getDeclaredMethods()) { try { ob.add(m.getName(), context.serialize(m.invoke(src))); } catch (Exception e) { throw new RuntimeException(e); } } JsonObject annOb = new JsonObject(); annOb.add(annType.getName(), ob); return annOb; } @Override public Annotation deserialize(JsonElement json, Type typeOfT, JsonDeserializationContext context) throws JsonParseException { JsonObject o = json.getAsJsonObject(); Set> entrySet = o.entrySet(); if (entrySet.size() != 1) { throw new JsonParseException("Annotation type with more than one property?"); } Entry kv = entrySet.iterator().next(); String annClassName = kv.getKey(); try { final Class annClass = Class.forName(annClassName, false, refLoader); final Map methods = Maps.newHashMap(); for (Entry e : kv.getValue().getAsJsonObject().entrySet()) { Method m = annClass.getMethod(e.getKey()); methods.put(m, context.deserialize(e.getValue(), m.getGenericReturnType())); } final Method annotationTypeMethod = Annotation.class.getMethod("annotationType"); InvocationHandler invHandler = new InvocationHandler() { @Override public Object invoke(Object proxy, Method method, Object[] args) throws Throwable { if (method.equals(annotationTypeMethod)) { return annClass; } else if (methods.containsKey(method)) { return methods.get(method); } return method.getDefaultValue(); } }; return (Annotation) Proxy.newProxyInstance(refLoader, new Class [] { annClass }, invHandler); } catch (Exception e) { throw new JsonParseException(e); } } }JsonByteArrayAdapter.java000066400000000000000000000042111235451432000407760ustar00rootroot00000000000000randomizedtesting-release-2.1.6/junit4-ant/src/main/java/com/carrotsearch/ant/tasks/junit4/events/jsonpackage com.carrotsearch.ant.tasks.junit4.events.json; import java.io.ByteArrayOutputStream; import java.lang.reflect.Type; import com.google.gson.*; /** * Serialize byte array to portable ASCII. This is used primarily to carry system streams * and since the encoding (or correctness) of these is generally not known we encode them * as binary to recover them faithfully. */ public class JsonByteArrayAdapter implements JsonSerializer, JsonDeserializer { private final static char [] HEX = "0123456789ABCDEF".toCharArray(); private final StringBuilder bb = new StringBuilder(); private final ByteArrayOutputStream baos = new ByteArrayOutputStream(); @Override public JsonElement serialize(byte[] src, Type typeOfSrc, JsonSerializationContext context) { return new JsonPrimitive(toAscii(src)); } private String toAscii(byte[] src) { bb.setLength(0); for (byte b : src) { // Pass simple ASCII range. if (b >= 32 && b <= 126 && b != '%') { bb.append((char) b); } else { bb.append('%'); bb.append(HEX[(b >> 4) & 0x0f]); bb.append(HEX[(b ) & 0x0f]); } } return bb.toString(); } private int hexValue(char hexChar) throws JsonParseException { if (hexChar >= '0' && hexChar <= '9') return hexChar - '0'; if (hexChar >= 'A' && hexChar <= 'F') return hexChar - 'A' + 10; if (hexChar >= 'a' && hexChar <= 'f') return hexChar - 'a' + 10; throw new JsonParseException("Unexpected character in binary stream: " + hexChar); } @Override public byte[] deserialize(JsonElement json, Type typeOfT, JsonDeserializationContext context) throws JsonParseException { if (typeOfT.equals(byte[].class)) throw new JsonParseException("Not a byte[]: " + typeOfT); String input = json.getAsString(); baos.reset(); for (int i = 0; i < input.length(); i++) { char chr = input.charAt(i); if (chr != '%') { baos.write(chr); } else { baos.write((hexValue(input.charAt(++i)) << 4) | hexValue(input.charAt(++i))); } } return baos.toByteArray(); } }JsonClassAdapter.java000066400000000000000000000014541235451432000401470ustar00rootroot00000000000000randomizedtesting-release-2.1.6/junit4-ant/src/main/java/com/carrotsearch/ant/tasks/junit4/events/jsonpackage com.carrotsearch.ant.tasks.junit4.events.json; import java.lang.reflect.Type; import com.google.gson.*; public class JsonClassAdapter implements JsonSerializer>, JsonDeserializer> { private final ClassLoader refLoader; public JsonClassAdapter(ClassLoader refLoader) { this.refLoader = refLoader; } @Override public JsonElement serialize(Class src, Type typeOfSrc, JsonSerializationContext context) { return new JsonPrimitive(src.getName()); } @Override public Class deserialize(JsonElement json, Type typeOfT, JsonDeserializationContext context) throws JsonParseException { try { return Class.forName(json.getAsString(), false, refLoader); } catch (ClassNotFoundException e) { throw new JsonParseException(e); } } }JsonDescriptionAdapter.java000066400000000000000000000072041235451432000413640ustar00rootroot00000000000000randomizedtesting-release-2.1.6/junit4-ant/src/main/java/com/carrotsearch/ant/tasks/junit4/events/jsonpackage com.carrotsearch.ant.tasks.junit4.events.json; import java.lang.annotation.Annotation; import java.lang.reflect.Type; import java.util.List; import org.junit.runner.Description; import com.google.common.collect.*; import com.google.gson.*; /** * Serialization and deserialization of {@link Description} instances. */ public class JsonDescriptionAdapter implements JsonSerializer, JsonDeserializer { private static class ComparableDescription { final String id; final Description description; public ComparableDescription(Description description) { this.description = description; this.id = createId(description); } private String createId(Description description) { // TODO: We include annotation count, but not their content. Is this wrong? StringBuilder builder = new StringBuilder(); builder.append("id#") .append(description.getDisplayName()); builder.append("[") .append(description.getAnnotations().size()) .append("]"); return builder.toString(); } @Override public int hashCode() { return id.hashCode(); } @Override public boolean equals(Object obj) { if (obj instanceof ComparableDescription) { return id.equals(((ComparableDescription) obj).id); } else { return false; } } } private final BiMap identifiers; private final BiMap identifiersInverse; public JsonDescriptionAdapter() { identifiers = HashBiMap.create(); identifiersInverse = identifiers.inverse(); } @Override public JsonElement serialize(Description e, Type type, JsonSerializationContext context) { final ComparableDescription key = new ComparableDescription(e); String id = identifiers.get(key); if (id != null) { return new JsonPrimitive(id); } else { id = key.id; identifiers.put(key, key.id); JsonObject object = new JsonObject(); object.addProperty("id", id); object.addProperty("displayName", e.getDisplayName()); object.addProperty("methodName", e.getMethodName()); object.addProperty("className", e.getClassName()); object.add("annotations", context.serialize(e.getAnnotations())); object.add("children", context.serialize(e.getChildren())); return object; } } @Override public Description deserialize(JsonElement json, Type typeOfT, JsonDeserializationContext context) throws JsonParseException { // Check if it's a full description or resolve backreference. if (json.isJsonPrimitive()) { String id = json.getAsString(); ComparableDescription key = identifiersInverse.get(id); if (key == null) { throw new JsonParseException("No such reference: " + id); } return key.description; } else { JsonObject o = json.getAsJsonObject(); List annotations = Lists.newArrayList(); for (JsonElement child : o.getAsJsonArray("annotations")) { annotations.add((Annotation) context.deserialize(child, Annotation.class)); } String displayName = o.getAsJsonPrimitive("displayName").getAsString(); Description description = Description.createSuiteDescription(displayName, annotations.toArray(new Annotation[annotations.size()])); for (JsonElement child : o.getAsJsonArray("children")) { description.addChild(deserialize(child, typeOfT, context)); } ComparableDescription key = new ComparableDescription(description); identifiers.put(key, key.id); return description; } } } 000077500000000000000000000000001235451432000346245ustar00rootroot00000000000000randomizedtesting-release-2.1.6/junit4-ant/src/main/java/com/carrotsearch/ant/tasks/junit4/events/mirrorsFailureMirror.java000066400000000000000000000043141235451432000402530ustar00rootroot00000000000000randomizedtesting-release-2.1.6/junit4-ant/src/main/java/com/carrotsearch/ant/tasks/junit4/events/mirrorspackage com.carrotsearch.ant.tasks.junit4.events.mirrors; import java.io.*; import org.junit.internal.AssumptionViolatedException; import org.junit.runner.Description; import org.junit.runner.notification.Failure; /** * A type-safe mirror of {@link Failure}. */ public class FailureMirror { private String message; private String trace; private String throwableString; private String throwableClass; /** Was [@link Failure} an instance of an {@link AssertionError}? */ private boolean assertionViolation; private boolean assumptionViolation; /** Serialized byte[] form of the original failure or null if it couldn't be serialized. */ private SerializableMirror serialized; /** The test {@link Description} that caused this failure. */ private Description description; public FailureMirror(Failure failure) { this.serialized = SerializableMirror.of(failure); this.message = failure.getMessage(); this.description = failure.getDescription(); this.trace = failure.getTrace(); final Throwable cause = failure.getException(); this.assertionViolation = cause instanceof AssertionError; this.assumptionViolation = cause instanceof AssumptionViolatedException; this.throwableString = cause.toString(); this.throwableClass = cause.getClass().getName(); } public String getMessage() { return message; } public String getThrowableString() { return throwableString; } public Description getDescription() { return description; } public String getTrace() { return trace; } /** * Try to deserialize the failure's cause. Context class loader is used * for class lookup. May cause side effects (class loading, static blocks, etc.) */ public Throwable getThrowable() throws ClassNotFoundException, IOException { return serialized.getDeserialized().getException(); } public boolean isAssumptionViolation() { return assumptionViolation; } public boolean isAssertionViolation() { return assertionViolation; } public boolean isErrorViolation() { return isAssertionViolation() == false && isAssumptionViolation() == false; } public String getThrowableClass() { return throwableClass; } } SerializableMirror.java000066400000000000000000000023621235451432000412730ustar00rootroot00000000000000randomizedtesting-release-2.1.6/junit4-ant/src/main/java/com/carrotsearch/ant/tasks/junit4/events/mirrorspackage com.carrotsearch.ant.tasks.junit4.events.mirrors; import java.io.*; /** * Serialization utilities. */ class SerializableMirror { private byte[] bytes; private SerializableMirror() { // No-args for json. } private SerializableMirror(T t) { bytes = tryToSerialize(t); } protected byte[] getBytes() { return bytes; } /** * Attempt to reinstantiate the exception from serialized bytes. */ @SuppressWarnings("unchecked") protected T getDeserialized() throws ClassNotFoundException, IOException { if (bytes == null) return null; ObjectInputStream is = new ObjectInputStream( new ByteArrayInputStream(bytes)); return (T) is.readObject(); } private static byte[] tryToSerialize(E t) { if (t != null) { try { ByteArrayOutputStream os = new ByteArrayOutputStream(); ObjectOutputStream oos = new ObjectOutputStream(os); oos.writeObject(t); oos.close(); return os.toByteArray(); } catch (Throwable ignore) { // Ignore. } } return null; } public static SerializableMirror of(T t) { return new SerializableMirror(t); } } 000077500000000000000000000000001235451432000336335ustar00rootroot00000000000000randomizedtesting-release-2.1.6/junit4-ant/src/main/java/com/carrotsearch/ant/tasks/junit4/listenersAggregatedEventListener.java000066400000000000000000000013461235451432000412440ustar00rootroot00000000000000randomizedtesting-release-2.1.6/junit4-ant/src/main/java/com/carrotsearch/ant/tasks/junit4/listenerspackage com.carrotsearch.ant.tasks.junit4.listeners; import org.apache.tools.ant.BuildException; import com.carrotsearch.ant.tasks.junit4.JUnit4; import com.carrotsearch.ant.tasks.junit4.events.aggregated.*; import com.google.common.eventbus.EventBus; /** * A dummy interface to indicate listener types for ANT. {@link JUnit4} uses * guava's {@link EventBus} to propagate events to listeners. * * @see AggregatedSuiteResultEvent * @see AggregatedTestResultEvent * @see AggregatedQuitEvent */ public interface AggregatedEventListener { /** * Link to the container. Listener can throw {@link BuildException} if * parameter validation doesn't succeed, for example. */ void setOuter(JUnit4 junit) throws BuildException; } ExecutionTimesReport.java000066400000000000000000000153121235451432000406410ustar00rootroot00000000000000randomizedtesting-release-2.1.6/junit4-ant/src/main/java/com/carrotsearch/ant/tasks/junit4/listenerspackage com.carrotsearch.ant.tasks.junit4.listeners; import java.io.BufferedReader; import java.io.BufferedWriter; import java.io.File; import java.io.FileInputStream; import java.io.IOException; import java.io.InputStream; import java.io.InputStreamReader; import java.util.Collection; import java.util.Iterator; import java.util.List; import java.util.Map; import java.util.SortedMap; import java.util.TreeMap; import org.apache.tools.ant.BuildException; import org.apache.tools.ant.Project; import org.apache.tools.ant.types.Resource; import org.apache.tools.ant.types.ResourceCollection; import com.carrotsearch.ant.tasks.junit4.JUnit4; import com.carrotsearch.ant.tasks.junit4.events.aggregated.AggregatedQuitEvent; import com.carrotsearch.ant.tasks.junit4.events.aggregated.AggregatedSuiteResultEvent; import com.google.common.base.Charsets; import com.google.common.base.Joiner; import com.google.common.collect.Lists; import com.google.common.collect.Maps; import com.google.common.eventbus.Subscribe; import com.google.common.io.Closer; import com.google.common.io.Files; /** * A report listener that emits per-suite execution times information useful * for load balancing tests across JVMs. */ public class ExecutionTimesReport implements AggregatedEventListener { /** * @see #setHistoryLength(int) */ public final static int DEFAULT_HISTORY_LENGTH = 10; /** * The file where suite hints are stored/ updated. */ private File hintsFile; /** * Execution time hints. Key: suite name, value: execution times. */ private Map> hints; /** * @see #setHistoryLength(int) */ private int historyLength = DEFAULT_HISTORY_LENGTH; /** * Outer task. */ private JUnit4 outer; /** * Hints file (key-value pairs). */ public void setFile(File hintsFile) { this.hintsFile = hintsFile; } /** * How many execution times to store per-suite? The history must be larger than 0. */ public void setHistoryLength(int length) { if (length < 0) { throw new BuildException("History length must be >= 1: " + length); } this.historyLength = length; } /** * Remember execution time for all executed suites. */ @Subscribe public void onSuiteResult(AggregatedSuiteResultEvent e) { long millis = e.getExecutionTime(); String suiteName = e.getDescription().getDisplayName(); List values = hints.get(suiteName); if (values == null) { hints.put(suiteName, values = Lists.newArrayList()); } values.add(millis); while (values.size() > historyLength) values.remove(0); } /** * Write back to hints file. */ @Subscribe public void onEnd(AggregatedQuitEvent e) { try { writeHints(hintsFile, hints); } catch (IOException exception) { outer.log("Could not write back the hints file.", exception, Project.MSG_ERR); } } @Override public void setOuter(JUnit4 outer) throws BuildException { if (hintsFile == null) { throw new BuildException( "Execution times listener requires file attribute."); } // If the file already exists, read its contents. try { if (hintsFile.isFile()) { hints = readHints(hintsFile); } else { if (!hintsFile.createNewFile()) { throw new BuildException("Could not create file: " + hintsFile.getAbsolutePath()); } hints = Maps.newHashMap(); } } catch (IOException e) { throw new BuildException("Could not read or create hints file: " + hintsFile.getAbsolutePath(), e); } this.outer = outer; } /** * Read hints from a file. */ public static Map> readHints(File hints) throws IOException { Map> result = Maps.newHashMap(); InputStream is = new FileInputStream(hints); mergeHints(is, result); return result; } /** * Read hints from a file and merge with the given hints map. */ public static void mergeHints(InputStream is, Map> hints) throws IOException { final BufferedReader reader = new BufferedReader( new InputStreamReader(is, Charsets.UTF_8)); String line; while ((line = reader.readLine()) != null) { line = line.trim(); if (line.isEmpty() || line.startsWith("#")) continue; final int equals = line.indexOf('='); if (equals <= 0) { throw new IOException("No '=' character on a non-comment line?: " + line); } else { String key = line.substring(0, equals); List values = hints.get(key); if (values == null) { hints.put(key, values = Lists.newArrayList()); } for (String v : line.substring(equals + 1).split("[\\,]")) { if (!v.isEmpty()) values.add(Long.parseLong(v)); } } } } /** * Writes back hints file. */ public static void writeHints(File file, Map> hints) throws IOException { Closer closer = Closer.create(); try { BufferedWriter w = closer.register(Files.newWriter(file, Charsets.UTF_8)); if (!(hints instanceof SortedMap)) { hints = new TreeMap>(hints); } Joiner joiner = Joiner.on(','); for (Map.Entry> e : hints.entrySet()) { w.write(e.getKey()); w.write("="); joiner.appendTo(w, e.getValue()); w.write("\n"); } } catch (Throwable t) { throw closer.rethrow(t); } finally { closer.close(); } } /** * Read hints from all resources in a collection, retaining * suiteNames. If suiteNames is null, * everything is retained. */ public static Map> mergeHints( Collection resources, Collection suiteNames) { final Map> hints = Maps.newHashMap(); for (ResourceCollection rc : resources) { @SuppressWarnings("unchecked") Iterator i = rc.iterator(); while (i.hasNext()) { InputStream is = null; Resource r = i.next(); try { is = r.getInputStream(); mergeHints(is, hints); // Early prune the hints to those we have on the list. if (suiteNames != null) { hints.keySet().retainAll(suiteNames); } } catch (IOException e) { throw new BuildException("Could not read hints from resource: " + r.getDescription(), e); } finally { try { if (is != null) is.close(); } catch (IOException e) { throw new BuildException("Could not close hints file: " + r.getDescription()); } } } } return hints; } } LineFlushingWriter.java000066400000000000000000000025151235451432000402650ustar00rootroot00000000000000randomizedtesting-release-2.1.6/junit4-ant/src/main/java/com/carrotsearch/ant/tasks/junit4/listenerspackage com.carrotsearch.ant.tasks.junit4.listeners; import java.io.IOException; import java.io.Writer; class LineFlushingWriter extends Writer { private Writer w; public LineFlushingWriter(Writer w) { this.w = w; } @Override public void write(int c) throws IOException { w.write(c); if (c == '\n') flush(); } @Override public void write(char[] cbuf, int off, int len) throws IOException { w.write(cbuf, off, len); for (int i = 0; i < len; i++) { if (cbuf[off + i] == '\n') { flush(); break; } } } @Override public void write(String str, int off, int len) throws IOException { w.write(str, off, len); for (int i = 0; i < len; i++) { if (str.charAt(off + i) == '\n') { flush(); break; } } } @Override public Writer append(char c) throws IOException { throw new UnsupportedOperationException(); } @Override public Writer append(CharSequence csq) throws IOException { throw new UnsupportedOperationException(); } @Override public Writer append(CharSequence csq, int start, int end) throws IOException { throw new UnsupportedOperationException(); } @Override public void flush() throws IOException { w.flush(); } @Override public void close() throws IOException { w.close(); } } PrefixedWriter.java000066400000000000000000000030411235451432000374370ustar00rootroot00000000000000randomizedtesting-release-2.1.6/junit4-ant/src/main/java/com/carrotsearch/ant/tasks/junit4/listenerspackage com.carrotsearch.ant.tasks.junit4.listeners; import java.io.IOException; import java.io.Writer; /** * Prefixes every new line with a given byte [], synchronizing multiple streams to emit consistent lines. */ class PrefixedWriter extends Writer { private final static char LF = '\n'; private final Writer sink; private final String prefix; private final StringBuilder lineBuffer = new StringBuilder(); private final int maxLineLength; public PrefixedWriter(String prefix, Writer sink, int maxLineLength) { super(sink); this.sink = sink; this.prefix = prefix; this.maxLineLength = maxLineLength; } @Override public void write(int c) throws IOException { if (lineBuffer.length() == maxLineLength || c == LF) { sink.write(prefix); sink.write(lineBuffer.toString()); sink.write(LF); lineBuffer.setLength(0); if (c != LF) { lineBuffer.append((char) c); } } else { lineBuffer.append((char) c); } } @Override public void write(char[] cbuf, int off, int len) throws IOException { for (int i = off; i < off + len; i++) { write(cbuf[i]); } } @Override public void flush() throws IOException { // don't pass flushes. } @Override public void close() throws IOException { throw new UnsupportedOperationException(); } /** * Complete the current line (emit LF if not at the start of the line already). */ public void completeLine() throws IOException { if (lineBuffer.length() > 0) { write(LF); } } } StackTraceFilter.java000066400000000000000000000051031235451432000376670ustar00rootroot00000000000000randomizedtesting-release-2.1.6/junit4-ant/src/main/java/com/carrotsearch/ant/tasks/junit4/listenerspackage com.carrotsearch.ant.tasks.junit4.listeners; import java.util.Arrays; import java.util.List; import java.util.regex.Pattern; import org.apache.tools.ant.filters.TokenFilter; import com.google.common.base.Joiner; import com.google.common.collect.Lists; /** * Stack trace filtering. */ public class StackTraceFilter { /** * Default stack trace filters. * * @see #setDefaults(boolean) */ private static List defaultFilters = Arrays.asList( // junit4 Pattern.compile("^(\\s+at )(org\\.junit\\.)"), Pattern.compile("^(\\s+at )(junit\\.framework\\.JUnit4TestAdapter)"), // sun/ reflection Pattern.compile("^(\\s+at )(sun\\.reflect\\.)"), Pattern.compile("^(\\s+at )(java\\.lang\\.reflect\\.Method\\.invoke\\()"), // randomizedtesting's own launcher. Pattern.compile("^(\\s+at )(com\\.carrotsearch\\.ant\\.tasks\\.junit4\\.slave\\.SlaveMain)")); /** * Whether or not to use the default filters. */ private boolean useDefaults = true; /** * Whether or not to use this filter (just in case somebody wanted to disable * it via a property). */ private boolean enabled = true; /** * Custom filters (from ANT's own TokenFilter). */ private List customFilters = Lists.newArrayList(); /** * Use default filters (JUnit, randomized testing, some of the reflection stuff). */ public void setDefaults(boolean useDefaults) { this.useDefaults = useDefaults; } /** * Disable or enable the filter. */ public void setEnabled(boolean enabled) { this.enabled = enabled; } /** */ public void addContainsString(TokenFilter.ContainsString filter) { addConfigured(filter); } /** */ public void addContainsRegex(TokenFilter.ContainsRegex filter) { addConfigured(filter); } /** * Add a custom filter. */ public void addConfigured(TokenFilter.Filter filter) { customFilters.add(filter); } public String apply(String trace) { if (!enabled) return trace; List lines = Arrays.asList(trace.split("[\r\n]+")); List out = Lists.newArrayList(); nextLine: for (String line : lines) { if (useDefaults) { for (Pattern p : defaultFilters) { if (p.matcher(line).find()) { continue nextLine; } } } for (TokenFilter.Filter customFilter : customFilters) { if (customFilter.filter(line) != null) { continue nextLine; } } out.add(line); } return Joiner.on("\n").join(out); } } TextReport.java000066400000000000000000000516761235451432000366350ustar00rootroot00000000000000randomizedtesting-release-2.1.6/junit4-ant/src/main/java/com/carrotsearch/ant/tasks/junit4/listenerspackage com.carrotsearch.ant.tasks.junit4.listeners; import static com.carrotsearch.ant.tasks.junit4.FormattingUtils.formatDescription; import static com.carrotsearch.ant.tasks.junit4.FormattingUtils.formatDurationInSeconds; import static com.carrotsearch.ant.tasks.junit4.FormattingUtils.formatTime; import static com.carrotsearch.ant.tasks.junit4.FormattingUtils.formatTimestamp; import java.io.File; import java.io.IOException; import java.io.OutputStreamWriter; import java.io.StringWriter; import java.io.Writer; import java.nio.charset.Charset; import java.util.Arrays; import java.util.EnumMap; import java.util.HashSet; import java.util.IdentityHashMap; import java.util.List; import java.util.Locale; import java.util.Set; import org.apache.commons.io.output.WriterOutputStream; import org.apache.tools.ant.BuildException; import org.apache.tools.ant.Project; import org.junit.runner.Description; import com.carrotsearch.ant.tasks.junit4.FormattingUtils; import com.carrotsearch.ant.tasks.junit4.JUnit4; import com.carrotsearch.ant.tasks.junit4.Pluralize; import com.carrotsearch.ant.tasks.junit4.events.IEvent; import com.carrotsearch.ant.tasks.junit4.events.IStreamEvent; import com.carrotsearch.ant.tasks.junit4.events.SuiteStartedEvent; import com.carrotsearch.ant.tasks.junit4.events.TestFinishedEvent; import com.carrotsearch.ant.tasks.junit4.events.aggregated.AggregatedQuitEvent; import com.carrotsearch.ant.tasks.junit4.events.aggregated.AggregatedResultEvent; import com.carrotsearch.ant.tasks.junit4.events.aggregated.AggregatedStartEvent; import com.carrotsearch.ant.tasks.junit4.events.aggregated.AggregatedSuiteResultEvent; import com.carrotsearch.ant.tasks.junit4.events.aggregated.AggregatedSuiteStartedEvent; import com.carrotsearch.ant.tasks.junit4.events.aggregated.AggregatedTestResultEvent; import com.carrotsearch.ant.tasks.junit4.events.aggregated.ChildBootstrap; import com.carrotsearch.ant.tasks.junit4.events.aggregated.HeartBeatEvent; import com.carrotsearch.ant.tasks.junit4.events.aggregated.PartialOutputEvent; import com.carrotsearch.ant.tasks.junit4.events.aggregated.TestStatus; import com.carrotsearch.ant.tasks.junit4.events.mirrors.FailureMirror; import com.google.common.base.Charsets; import com.google.common.base.Strings; import com.google.common.collect.Lists; import com.google.common.collect.Maps; import com.google.common.eventbus.Subscribe; import com.google.common.io.CharSink; import com.google.common.io.Closeables; import com.google.common.io.FileWriteMode; import com.google.common.io.Files; /** * A listener that will subscribe to test execution and dump * informational info about the progress to the console or a text * file. */ @SuppressWarnings("resource") public class TextReport implements AggregatedEventListener { /* * Indents for outputs. */ private static final String indent = " > "; private static final String stdoutIndent = " 1> "; private static final String stderrIndent = " 2> "; /** * Failure marker string. */ private static final String FAILURE_MARKER = " <<<"; private static final String FAILURE_STRING = FAILURE_MARKER + " FAILURES!"; /** * Default 16kb for maximum line width buffer. Otherwise we may get OOMs buffering * each line. */ private static final int DEFAULT_MAX_LINE_WIDTH = 1024 * 16; /** * Code pages which are capable of displaying all unicode glyphs. */ private static Set UNICODE_ENCODINGS = new HashSet(Arrays.asList( "UTF-8", "UTF-16LE", "UTF-16", "UTF-16BE", "UTF-32")); /** * Display mode for output streams. */ public static enum OutputMode { /** Always display the output emitted from tests. */ ALWAYS, /** * Display the output only if a test/ suite failed. This requires internal buffering * so the output will be shown only after a test completes. */ ONERROR, /** * Don't display the output, even on test failures. */ NEVER; } /** * Status names column. */ private static EnumMap statusNames; static { statusNames = Maps.newEnumMap(TestStatus.class); for (TestStatus s : TestStatus.values()) { statusNames.put(s, s == TestStatus.IGNORED_ASSUMPTION ? "IGNOR/A" : s.toString()); } } /** @see #setShowThrowable(boolean) */ private boolean showThrowable = true; /** @see #setShowStackTraces(boolean) */ private boolean showStackTraces = true; /** @see #setShowOutput(String) */ private OutputMode outputMode = OutputMode.ALWAYS; /** @see #setShowSuiteSummary(boolean) */ private boolean showSuiteSummary = true; /** @see #showEmptySuites(boolean) */ private boolean showEmptySuites = false; /** * Status display info. */ private final EnumMap displayStatus; /** * Initialize {@link #displayStatus}. */ { displayStatus = Maps.newEnumMap(TestStatus.class); for (TestStatus s : TestStatus.values()) { displayStatus.put(s, true); } } /** * A {@link Writer} for writing output messages. */ private Writer output; /** * Maximum number of columns for class name. */ private int maxClassNameColumns = Integer.MAX_VALUE; /** * Use simple names for suite names. */ private boolean useSimpleNames = false; /** * Display timestamps and durations for tests/ suites. */ private boolean timestamps = false; /** * {@link #output} file name. */ private File outputFile; /** * Append to {@link #outputFile} if specified. */ private boolean append; /** * Forked concurrent JVM count. */ private int forkedJvmCount; /** * Format line for JVM ID string. */ private String jvmIdFormat; /** Standard output, prefixed and decoded. */ private PrefixedWriter outWriter; /** Standard error, prefixed and decoded. */ private PrefixedWriter errWriter; /** sysout recode stream. */ private WriterOutputStream outStream; /** syserr recode stream. */ private WriterOutputStream errStream; /** Summarize the first N failures at the end. */ private int showNumFailuresAtEnd = 3; /** A list of failed tests, if to be displayed at the end. */ private List failedTests = Lists.newArrayList(); /** Stack trace filters. */ private List stackFilters = Lists.newArrayList(); public void setShowStatusError(boolean showStatus) { displayStatus.put(TestStatus.ERROR, showStatus); } public void setShowStatusFailure(boolean showStatus) { displayStatus.put(TestStatus.FAILURE, showStatus); } public void setShowStatusOk(boolean showStatus) { displayStatus.put(TestStatus.OK, showStatus); } public void setShowStatusIgnored(boolean showStatus) { displayStatus.put(TestStatus.IGNORED, showStatus); displayStatus.put(TestStatus.IGNORED_ASSUMPTION, showStatus); } /** * Set maximum number of class name columns before truncated with ellipsis. */ public void setMaxClassNameColumns(int maxClassNameColumns) { this.maxClassNameColumns = maxClassNameColumns; } /** * Use simple class names for suite naming. */ public void setUseSimpleNames(boolean useSimpleNames) { this.useSimpleNames = useSimpleNames; } /** * Show duration timestamps for tests and suites. */ public void setTimestamps(boolean timestamps) { this.timestamps = timestamps; } /** * Filter stack traces from certain frames. */ public void addConfigured(StackTraceFilter sfilter) { this.stackFilters.add(sfilter); } /** * If enabled, displays extended error information for tests that failed * (exception class, message, stack trace, standard streams). * * @see #setShowStackTraces(boolean) */ public void setShowThrowable(boolean showThrowable) { this.showThrowable = showThrowable; } /** * Show stack trace information. */ public void setShowStackTraces(boolean showStackTraces) { this.showStackTraces = showStackTraces; } /** * Display mode for output streams. */ public void setShowOutput(String mode) { try { this.outputMode = OutputMode.valueOf(mode.toUpperCase()); } catch (IllegalArgumentException e) { throw new IllegalArgumentException("showOutput accepts any of: " + Arrays.toString(OutputMode.values()) + ", value is not valid: " + mode); } } /** * Summarize N failures at the end of the report. */ public void setShowNumFailures(int num) { this.showNumFailuresAtEnd = num; } /** * Display suites without any errors and with no tests (resulting from filtering * expressions, for example). */ public void setShowEmptySuites(boolean showEmptySuites) { this.showEmptySuites = showEmptySuites; } /** * If enabled, shows suite summaries in "maven-like" format of: *
   * Running SuiteName
   * [...suite tests if enabled...]
   * Tests: xx, Failures: xx, Errors: xx, Skipped: xx, Time: xx sec [<<< FAILURES!]
   * 
*/ public void setShowSuiteSummary(boolean showSuiteSummary) { this.showSuiteSummary = showSuiteSummary; } /** * Set an external file to write to. That file will always be in UTF-8. */ public void setFile(File outputFile) throws IOException { if (!outputFile.getName().isEmpty()) { this.outputFile = outputFile; } } /** * Append if {@link #setFile(File)} is also specified. */ public void setAppend(boolean append) { this.append = append; } /** * Initialization by container task {@link JUnit4}. */ @Override public void setOuter(JUnit4 task) { if (outputFile != null) { try { Files.createParentDirs(outputFile); final CharSink charSink; if (append) { charSink = Files.asCharSink(outputFile, Charsets.UTF_8, FileWriteMode.APPEND); } else { charSink = Files.asCharSink(outputFile, Charsets.UTF_8); } this.output = charSink.openBufferedStream(); } catch (IOException e) { throw new BuildException(e); } } else { if (!UNICODE_ENCODINGS.contains(Charset.defaultCharset().name())) { task.log("Your default console's encoding may not display certain" + " unicode glyphs: " + Charset.defaultCharset().name(), Project.MSG_INFO); } output = new LineFlushingWriter(new OutputStreamWriter(System.out, Charset.defaultCharset())) { @Override // Don't close the underlying stream, just flush. public void close() throws IOException { flush(); } }; } } /* * Test events subscriptions. */ @Subscribe public void onStart(AggregatedStartEvent e) throws IOException { logShort("Executing " + e.getSuiteCount() + Pluralize.pluralize(e.getSuiteCount(), " suite") + " with " + e.getSlaveCount() + Pluralize.pluralize(e.getSlaveCount(), " JVM") + ".\n", false); forkedJvmCount = e.getSlaveCount(); jvmIdFormat = " J%-" + (1 + (int) Math.floor(Math.log10(forkedJvmCount))) + "d"; outWriter = new PrefixedWriter(stdoutIndent, output, DEFAULT_MAX_LINE_WIDTH); errWriter = new PrefixedWriter(stderrIndent, output, DEFAULT_MAX_LINE_WIDTH); } @Subscribe public void onChildBootstrap(ChildBootstrap e) throws IOException { logShort("Started J" + e.getSlave().id + " PID(" + e.getSlave().getPidString() + ")."); } @Subscribe public void onHeartbeat(HeartBeatEvent e) throws IOException { logShort("HEARTBEAT J" + e.getSlave().id + " PID(" + e.getSlave().getPidString() + "): " + formatTime(e.getCurrentTime()) + ", stalled for " + formatDurationInSeconds(e.getNoEventDuration()) + " at: " + (e.getDescription() == null ? "" : formatDescription(e.getDescription()))); } @Subscribe public void onQuit(AggregatedQuitEvent e) throws IOException { if (showNumFailuresAtEnd > 0 && !failedTests.isEmpty()) { List sublist = this.failedTests; StringBuilder b = new StringBuilder(); b.append("\nTests with failures"); if (sublist.size() > showNumFailuresAtEnd) { sublist = sublist.subList(0, showNumFailuresAtEnd); b.append(" (first " + showNumFailuresAtEnd + " out of " + failedTests.size() + ")"); } b.append(":\n"); for (Description description : sublist) { b.append(" - ").append(formatDescription(description, true)).append("\n"); } b.append("\n"); logShort(b, false); } if (output != null) { Closeables.close(output, true); } } @Subscribe public void onSuiteStart(AggregatedSuiteStartedEvent e) throws IOException { final Charset charset = e.getSlave().getCharset(); outStream = new WriterOutputStream(outWriter, charset, DEFAULT_MAX_LINE_WIDTH, true); errStream = new WriterOutputStream(errWriter, charset, DEFAULT_MAX_LINE_WIDTH, true); if (showSuiteSummary && isPassthrough()) { SuiteStartedEvent evt = e.getSuiteStartedEvent(); emitSuiteStart(evt.getDescription(), evt.getStartTimestamp()); } } @Subscribe public void onOutput(PartialOutputEvent e) throws IOException { if (isPassthrough()) { // We only allow passthrough output if there is one JVM. switch (e.getEvent().getType()) { case APPEND_STDERR: ((IStreamEvent) e.getEvent()).copyTo(errStream); break; case APPEND_STDOUT: ((IStreamEvent) e.getEvent()).copyTo(outStream); break; default: break; } } } @Subscribe public void onTestResult(AggregatedTestResultEvent e) throws IOException { if (isPassthrough() && displayStatus.get(e.getStatus())) { flushOutput(); emitStatusLine(e, e.getStatus(), e.getExecutionTime()); } if (!e.isSuccessful() && showNumFailuresAtEnd > 0) { failedTests.add(e.getDescription()); } } @Subscribe public void onSuiteResult(AggregatedSuiteResultEvent e) throws IOException { if (e.isSuccessful() && e.getTests().isEmpty() && !showEmptySuites) { return; } // We must emit buffered test and stream events (in case of failures). if (!isPassthrough()) { if (showSuiteSummary) { emitSuiteStart(e.getDescription(), e.getStartTimestamp()); } emitBufferedEvents(e); } // Emit a synthetic failure for suite-level errors, if any. if (!e.getFailures().isEmpty() && displayStatus.get(TestStatus.ERROR)) { emitStatusLine(e, TestStatus.ERROR, 0); } if (!e.getFailures().isEmpty() && showNumFailuresAtEnd > 0) { failedTests.add(e.getDescription()); } // Emit suite summary line if requested. if (showSuiteSummary) { emitSuiteEnd(e); } } private void emitBufferedEvents(AggregatedSuiteResultEvent e) throws IOException { final IdentityHashMap eventMap = Maps.newIdentityHashMap(); for (AggregatedTestResultEvent tre : e.getTests()) { eventMap.put(tre.getTestFinishedEvent(), tre); } final boolean emitOutput = (outputMode != OutputMode.NEVER) && ((outputMode == OutputMode.ALWAYS && !isPassthrough()) || (outputMode == OutputMode.ONERROR && !e.isSuccessful())); for (IEvent event : e.getEventStream()) { switch (event.getType()) { case APPEND_STDOUT: if (emitOutput) ((IStreamEvent) event).copyTo(outStream); break; case APPEND_STDERR: if (emitOutput) ((IStreamEvent) event).copyTo(errStream); break; case TEST_FINISHED: assert eventMap.containsKey(event); final AggregatedTestResultEvent aggregated = eventMap.get(event); if (displayStatus.get(aggregated.getStatus())) { flushOutput(); emitStatusLine(aggregated, aggregated.getStatus(), aggregated.getExecutionTime()); } default: break; } } if (emitOutput) { flushOutput(); } } /** * Flush output streams. */ private void flushOutput() throws IOException { outStream.flush(); outWriter.completeLine(); errStream.flush(); errWriter.completeLine(); } /** * Suite prologue. */ private void emitSuiteStart(Description description, long startTimestamp) throws IOException { String suiteName = description.getDisplayName(); if (useSimpleNames) { if (suiteName.lastIndexOf('.') >= 0) { suiteName = suiteName.substring(suiteName.lastIndexOf('.') + 1); } } logShort(shortTimestamp(startTimestamp) + "Suite: " + FormattingUtils.padTo(maxClassNameColumns, suiteName, "[...]")); } /** * Suite end. */ private void emitSuiteEnd(AggregatedSuiteResultEvent e) throws IOException { assert showSuiteSummary; final StringBuilder b = new StringBuilder(); b.append(String.format(Locale.ENGLISH, "%sCompleted%s in %.2fs, ", shortTimestamp(e.getStartTimestamp() + e.getExecutionTime()), e.getSlave().slaves > 1 ? " on J" + e.getSlave().id : "", e.getExecutionTime() / 1000.0d)); b.append(e.getTests().size()).append(Pluralize.pluralize(e.getTests().size(), " test")); int failures = e.getFailureCount(); if (failures > 0) { b.append(", ").append(failures).append(Pluralize.pluralize(failures, " failure")); } int errors = e.getErrorCount(); if (errors > 0) { b.append(", ").append(errors).append(Pluralize.pluralize(errors, " error")); } int ignored = e.getIgnoredCount(); if (ignored > 0) { b.append(", ").append(ignored).append(" skipped"); } if (!e.isSuccessful()) { b.append(FAILURE_STRING); } b.append("\n"); logShort(b, false); } /** * Emit status line for an aggregated event. */ private void emitStatusLine(AggregatedResultEvent result, TestStatus status, long timeMillis) throws IOException { final StringBuilder line = new StringBuilder(); line.append(shortTimestamp(result.getStartTimestamp())); line.append(Strings.padEnd(statusNames.get(status), 8, ' ')); line.append(formatDurationInSeconds(timeMillis)); if (forkedJvmCount > 1) { line.append(String.format(Locale.ENGLISH, jvmIdFormat, result.getSlave().id)); } line.append(" | "); line.append(formatDescription(result.getDescription())); if (!result.isSuccessful()) { line.append(FAILURE_MARKER); } line.append("\n"); if (showThrowable) { // GH-82 (cause for ignored tests). if (status == TestStatus.IGNORED && result instanceof AggregatedTestResultEvent) { final StringWriter sw = new StringWriter(); PrefixedWriter pos = new PrefixedWriter(indent, sw, DEFAULT_MAX_LINE_WIDTH); pos.write("Cause: "); pos.write(((AggregatedTestResultEvent) result).getCauseForIgnored()); pos.completeLine(); line.append(sw.toString()); } final List failures = result.getFailures(); if (!failures.isEmpty()) { final StringWriter sw = new StringWriter(); PrefixedWriter pos = new PrefixedWriter(indent, sw, DEFAULT_MAX_LINE_WIDTH); int count = 0; for (FailureMirror fm : failures) { count++; if (fm.isAssumptionViolation()) { pos.write(String.format(Locale.ENGLISH, "Assumption #%d: %s", count, com.google.common.base.Objects.firstNonNull(fm.getMessage(), "(no message)"))); } else { pos.write(String.format(Locale.ENGLISH, "Throwable #%d: %s", count, showStackTraces ? filterStackTrace(fm.getTrace()) : fm.getThrowableString())); } } pos.completeLine(); if (sw.getBuffer().length() > 0) { line.append(sw.toString()); } } } logShort(line); } /** * Filter stack trace if {@link #addConfigured(StackTraceFilter)}. */ private String filterStackTrace(String trace) { for (StackTraceFilter filter : stackFilters) { trace = filter.apply(trace); } return trace; } /** * Log a message line to the output. */ private void logShort(CharSequence message, boolean trim) throws IOException { int length = message.length(); if (trim) { while (length > 0 && Character.isWhitespace(message.charAt(length - 1))) { length--; } } char [] chars = new char [length + 1]; for (int i = 0; i < length; i++) { chars[i] = message.charAt(i); } chars[length] = '\n'; output.write(chars); } /** * logShort, trim whitespace. */ private void logShort(CharSequence message) throws IOException { logShort(message, true); } /** * @return true if we can emit output directly and immediately. */ private boolean isPassthrough() { return forkedJvmCount == 1 && outputMode == OutputMode.ALWAYS; } /** * Format a short timestamp. */ private String shortTimestamp(long ts) { if (timestamps) { return "[" + formatTimestamp(ts) + "] "; } else { return ""; } } } 000077500000000000000000000000001235451432000351365ustar00rootroot00000000000000randomizedtesting-release-2.1.6/junit4-ant/src/main/java/com/carrotsearch/ant/tasks/junit4/listeners/antxmlAntXmlReport.java000066400000000000000000000207441235451432000404070ustar00rootroot00000000000000randomizedtesting-release-2.1.6/junit4-ant/src/main/java/com/carrotsearch/ant/tasks/junit4/listeners/antxmlpackage com.carrotsearch.ant.tasks.junit4.listeners.antxml; import java.io.File; import java.io.IOException; import java.io.Reader; import java.io.StringReader; import java.io.StringWriter; import java.text.SimpleDateFormat; import java.util.Date; import java.util.List; import java.util.Map; import org.apache.tools.ant.BuildException; import org.apache.tools.ant.Project; import org.apache.tools.ant.filters.TokenFilter; import org.junit.runner.Description; import org.simpleframework.xml.core.Persister; import org.simpleframework.xml.transform.RegistryMatcher; import com.carrotsearch.ant.tasks.junit4.JUnit4; import com.carrotsearch.ant.tasks.junit4.events.aggregated.AggregatedSuiteResultEvent; import com.carrotsearch.ant.tasks.junit4.events.aggregated.AggregatedTestResultEvent; import com.carrotsearch.ant.tasks.junit4.events.aggregated.TestStatus; import com.carrotsearch.ant.tasks.junit4.events.mirrors.FailureMirror; import com.carrotsearch.ant.tasks.junit4.listeners.AggregatedEventListener; import com.google.common.base.Strings; import com.google.common.base.Throwables; import com.google.common.collect.Lists; import com.google.common.collect.Maps; import com.google.common.eventbus.Subscribe; import com.google.common.io.CharStreams; import com.google.common.io.Files; /** * A report listener that produces XML files compatible with those produced by * ANT's default junit task. These files do not include full * information but many tools can parse them. */ public class AntXmlReport implements AggregatedEventListener { private JUnit4 junit4; private File dir; private boolean mavenExtensions = true; private List filters = Lists.newArrayList(); private Map suiteCounts = Maps.newHashMap(); private boolean ignoreDuplicateSuites; /** * @see #setOutputStreams(boolean) */ private boolean outputStreams = true; /** * Output directory to write reports to. */ public void setDir(File dir) { this.dir = dir; } /** * Include output streams? Mind that with large outputs the report may OOM. */ public void setOutputStreams(boolean outputStreams) { this.outputStreams = outputStreams; } /** * Emit maven elements in the XML (extensions compared to ANT). */ public void setMavenExtensions(boolean mavenExtensions) { this.mavenExtensions = mavenExtensions; } /** * Ignore duplicate suite names. */ public void setIgnoreDuplicateSuites(boolean ignoreDuplicateSuites) { this.ignoreDuplicateSuites = ignoreDuplicateSuites; } /** * Adds method name filter. */ public void addConfiguredTokenFilter(TokenFilter filter) { this.filters.add(filter); } /* * */ @Override public void setOuter(JUnit4 junit4) { this.junit4 = junit4; if (this.dir == null) { throw new BuildException("'dir' attribute is required (target folder for reports)."); } try { Files.createParentDirs(dir); dir.mkdir(); } catch (IOException e) { throw new BuildException("Could not create parent folders of: " + dir, e); } } /** * Emit information about all of suite's tests. */ @Subscribe public void onSuiteResult(AggregatedSuiteResultEvent e) { Description suiteDescription = e.getDescription(); String displayName = suiteDescription.getDisplayName(); if (displayName.trim().isEmpty()) { junit4.log("Could not emit XML report for suite (null description).", Project.MSG_WARN); return; } if (!suiteCounts.containsKey(displayName)) { suiteCounts.put(displayName, 1); } else { int newCount = suiteCounts.get(displayName) + 1; suiteCounts.put(displayName, newCount); if (!ignoreDuplicateSuites && newCount == 2) { junit4.log("Duplicate suite name used with XML reports: " + displayName + ". This may confuse tools that process XML reports. " + "Set 'ignoreDuplicateSuites' to true to skip this message.", Project.MSG_WARN); } displayName = displayName + "-" + newCount; } try { File reportFile = new File(dir, "TEST-" + displayName + ".xml"); RegistryMatcher rm = new RegistryMatcher(); rm.bind(String.class, new XmlStringTransformer()); Persister persister = new Persister(rm); persister.write(buildModel(e), reportFile); } catch (Exception x) { junit4.log("Could not serialize report for suite " + displayName + ": " + x.toString(), Project.MSG_WARN); } } /** * Build data model for serialization. */ private TestSuiteModel buildModel(AggregatedSuiteResultEvent e) throws IOException { SimpleDateFormat df = new SimpleDateFormat("yyyy-MM-dd'T'HH:mm:ss"); TestSuiteModel suite = new TestSuiteModel(); suite.hostname = "nohost.nodomain"; suite.name = e.getDescription().getDisplayName(); suite.properties = buildModel(e.getSlave().getSystemProperties()); suite.time = e.getExecutionTime() / 1000.0; suite.timestamp = df.format(new Date(e.getStartTimestamp())); suite.testcases = buildModel(e.getTests()); suite.tests = suite.testcases.size(); if (mavenExtensions) { suite.skipped = 0; } // Suite-level failures and errors are simulated as test cases. for (FailureMirror m : e.getFailures()) { TestCaseModel model = new TestCaseModel(); model.classname = "junit.framework.TestSuite"; // empirical ANT output. model.name = applyFilters(m.getDescription().getClassName()); model.time = 0; if (m.isAssertionViolation()) { model.failures.add(buildModel(m)); } else { model.errors.add(buildModel(m)); } suite.testcases.add(model); } // Calculate test numbers that match limited view (no ignored tests, // faked suite-level errors). for (TestCaseModel tc : suite.testcases) { suite.errors += tc.errors.size(); suite.failures += tc.failures.size(); if (mavenExtensions && tc.skipped != null) { suite.skipped += 1; } } StringWriter sysout = new StringWriter(); StringWriter syserr = new StringWriter(); if (outputStreams) { e.getSlave().decodeStreams(e.getEventStream(), sysout, syserr); } suite.sysout = sysout.toString(); suite.syserr = syserr.toString(); return suite; } /* */ private List buildModel(List testEvents) { List tests = Lists.newArrayList(); for (AggregatedTestResultEvent e : testEvents) { TestCaseModel model = new TestCaseModel(); if (e.getStatus() == TestStatus.IGNORED || e.getStatus() == TestStatus.IGNORED_ASSUMPTION) { if (mavenExtensions) { // This emits an empty element. model.skipped = ""; } else { // No way to report these in pure ANT XML. continue; } } model.name = applyFilters(e.getDescription().getMethodName()); model.classname = e.getDescription().getClassName(); model.time = e.getExecutionTime() / 1000.0; for (FailureMirror m : e.getFailures()) { if (m.isAssumptionViolation()) { // Assumptions are not represented in ANT or Maven XMLs. continue; } else if (m.isAssertionViolation()) { model.failures.add(buildModel(m)); } else { model.errors.add(buildModel(m)); } } tests.add(model); } return tests; } /** * Apply filters to a method name. * @param methodName */ private String applyFilters(String methodName) { if (filters.isEmpty()) { return methodName; } Reader in = new StringReader(methodName); for (TokenFilter tf : filters) { in = tf.chain(in); } try { return CharStreams.toString(in); } catch (IOException e) { junit4.log("Could not apply filters to " + methodName + ": " + Throwables.getStackTraceAsString(e), Project.MSG_WARN); return methodName; } } /* */ private FailureModel buildModel(FailureMirror f) { FailureModel model = new FailureModel(); model.message = Strings.nullToEmpty(f.getMessage()); model.text = f.getTrace(); model.type = f.getThrowableClass(); return model; } /* */ private List buildModel(Map properties) { List props = Lists.newArrayList(); for (Map.Entry e : properties.entrySet()) { props.add(new PropertyModel(e.getKey(), e.getValue())); } return props; } } FailureModel.java000066400000000000000000000004241235451432000403510ustar00rootroot00000000000000randomizedtesting-release-2.1.6/junit4-ant/src/main/java/com/carrotsearch/ant/tasks/junit4/listeners/antxmlpackage com.carrotsearch.ant.tasks.junit4.listeners.antxml; import org.simpleframework.xml.Attribute; import org.simpleframework.xml.Text; public class FailureModel { @Attribute public String message; @Attribute public String type; @Text public String text; } NotAnt.java000066400000000000000000000007041235451432000372050ustar00rootroot00000000000000randomizedtesting-release-2.1.6/junit4-ant/src/main/java/com/carrotsearch/ant/tasks/junit4/listeners/antxmlpackage com.carrotsearch.ant.tasks.junit4.listeners.antxml; import java.lang.annotation.ElementType; import java.lang.annotation.Retention; import java.lang.annotation.RetentionPolicy; import java.lang.annotation.Target; /** * Local markup to indicate which elements are extensions and where. */ @Retention(RetentionPolicy.SOURCE) @Target({ElementType.FIELD, ElementType.METHOD}) @interface NotAnt { String extensionSource() default "junit4"; } PropertyModel.java000066400000000000000000000007461235451432000406150ustar00rootroot00000000000000randomizedtesting-release-2.1.6/junit4-ant/src/main/java/com/carrotsearch/ant/tasks/junit4/listeners/antxmlpackage com.carrotsearch.ant.tasks.junit4.listeners.antxml; import org.simpleframework.xml.Attribute; import org.simpleframework.xml.Root; import com.google.common.base.Strings; @Root(name = "property") public class PropertyModel { @Attribute(required = true) public String name; @Attribute(required = true) public String value; public PropertyModel(String key, String value) { this.name = Strings.nullToEmpty(key); this.value = Strings.nullToEmpty(value); } } TestCaseModel.java000066400000000000000000000016701235451432000405010ustar00rootroot00000000000000randomizedtesting-release-2.1.6/junit4-ant/src/main/java/com/carrotsearch/ant/tasks/junit4/listeners/antxmlpackage com.carrotsearch.ant.tasks.junit4.listeners.antxml; import java.util.List; import org.simpleframework.xml.Attribute; import org.simpleframework.xml.Element; import org.simpleframework.xml.ElementList; import org.simpleframework.xml.Root; import com.google.common.collect.Lists; @Root(name = "testcase") public class TestCaseModel { @Attribute(required = true) public String classname; @Attribute(required = true) public String name; @Attribute(required = true) public double time; @ElementList(inline = true, entry = "failure", required = false, type = FailureModel.class) public List failures = Lists.newArrayList(); @ElementList(inline = true, entry = "error", required = false, type = FailureModel.class) public List errors = Lists.newArrayList(); @NotAnt(extensionSource = "maven") @Element(name = "skipped", required = false) public String skipped; }TestSuiteModel.java000066400000000000000000000024641235451432000407210ustar00rootroot00000000000000randomizedtesting-release-2.1.6/junit4-ant/src/main/java/com/carrotsearch/ant/tasks/junit4/listeners/antxmlpackage com.carrotsearch.ant.tasks.junit4.listeners.antxml; import java.util.List; import org.simpleframework.xml.Attribute; import org.simpleframework.xml.Element; import org.simpleframework.xml.ElementList; import org.simpleframework.xml.Root; import com.google.common.collect.Lists; /** * Suite model of ANT-JUnit XML. */ @Root(name = "testsuite") public class TestSuiteModel { @Attribute public int errors; @Attribute public int failures; /** */ @Attribute public int tests; /** The number of skipped tests (maven surefire). */ @NotAnt(extensionSource = "maven") @Attribute(required = false) public Integer skipped; @Attribute public String name; @Attribute public String hostname; @Attribute public double time; @Attribute public String timestamp; @ElementList(type = PropertyModel.class) public List properties = Lists.newArrayList(); @ElementList(inline = true, type = TestCaseModel.class) public List testcases = Lists.newArrayList(); @Element(name = "system-out", data = true, required = true) public String sysout = ""; @Element(name = "system-err", data = true, required = true) public String syserr = ""; }XmlStringTransformer.java000066400000000000000000000031571235451432000421610ustar00rootroot00000000000000randomizedtesting-release-2.1.6/junit4-ant/src/main/java/com/carrotsearch/ant/tasks/junit4/listeners/antxmlpackage com.carrotsearch.ant.tasks.junit4.listeners.antxml; import org.simpleframework.xml.transform.Transform; final class XmlStringTransformer implements Transform { private final StringBuilder buffer = new StringBuilder(); @Override public String read(String value) throws Exception { return value; } @Override public String write(String value) throws Exception { if (!isMappableXmlText(value)) { return remap(value); } return value; } private String remap(CharSequence value) { buffer.setLength(0); final int length = value.length(); for (int i = 0; i < length; i = Character.offsetByCodePoints(value, i, 1)) { int cp = Character.codePointAt(value, i); if ((cp >= 0x20 && cp <= 0x00D7FF) || (cp < 0x20 && (cp == 0x09 || cp == 0x0A || cp == 0x0D)) || (cp >= 0xE000 && cp <= 0x00FFFD) || (cp >= 0x10000 && cp <= 0x10FFFF)) { buffer.appendCodePoint(cp); } else { buffer.append(/* Replacement char. */ "\ufffd"); } } return buffer.toString(); } private static boolean isMappableXmlText(CharSequence value) { final int length = value.length(); for (int i = 0; i < length; i = Character.offsetByCodePoints(value, i, 1)) { int cp = Character.codePointAt(value, i); if ((cp >= 0x20 && cp <= 0x00D7FF) || (cp < 0x20 && (cp == 0x09 || cp == 0x0A || cp == 0x0D)) || (cp >= 0xE000 && cp <= 0x00FFFD) || (cp >= 0x10000 && cp <= 0x10FFFF)) { // Ok, mappable XML character. } else { return false; } } return true; } } 000077500000000000000000000000001235451432000346045ustar00rootroot00000000000000randomizedtesting-release-2.1.6/junit4-ant/src/main/java/com/carrotsearch/ant/tasks/junit4/listeners/jsonJsonAggregatedSuiteResultEventAdapter.java000066400000000000000000000102121235451432000450430ustar00rootroot00000000000000randomizedtesting-release-2.1.6/junit4-ant/src/main/java/com/carrotsearch/ant/tasks/junit4/listeners/jsonpackage com.carrotsearch.ant.tasks.junit4.listeners.json; import java.io.IOException; import java.io.StringWriter; import java.lang.reflect.Type; import java.util.Date; import org.apache.commons.io.output.WriterOutputStream; import com.carrotsearch.ant.tasks.junit4.ForkedJvmInfo; import com.carrotsearch.ant.tasks.junit4.events.*; import com.carrotsearch.ant.tasks.junit4.events.aggregated.AggregatedSuiteResultEvent; import com.google.gson.*; import static com.carrotsearch.ant.tasks.junit4.events.EventType.*; /** * Serialization of {@link AggregatedSuiteResultEvent}. */ public class JsonAggregatedSuiteResultEventAdapter implements JsonSerializer { private final boolean outputStreams; public JsonAggregatedSuiteResultEventAdapter(boolean outputStreams) { this.outputStreams = outputStreams; } @Override public JsonElement serialize(AggregatedSuiteResultEvent e, Type type, JsonSerializationContext context) { JsonObject suite = new JsonObject(); suite.addProperty("slave", e.getSlave().id); suite.addProperty("startTimestamp", e.getStartTimestamp()); suite.add("startTimestampDate", context.serialize(new Date(e.getStartTimestamp()))); suite.addProperty("executionTime", e.getExecutionTime()); suite.add("description", context.serialize(e.getDescription())); suite.add("tests", context.serialize(e.getTests())); suite.add("suiteFailures", context.serialize(e.getFailures())); suite.add("executionEvents", serializeEvents(e, context)); return suite; } public JsonArray serializeEvents(AggregatedSuiteResultEvent e, JsonSerializationContext context) { final JsonArray output = new JsonArray(); final ForkedJvmInfo slave = e.getSlave(); int lineBuffer = 160; final StringWriter out = new StringWriter(); final StringWriter err = new StringWriter(); WriterOutputStream stdout = new WriterOutputStream(out, slave.getCharset(), lineBuffer, false); WriterOutputStream stderr = new WriterOutputStream(err, slave.getCharset(), lineBuffer, false); for (IEvent evt : e.getEventStream()) { try { JsonObject marker; switch (evt.getType()) { case SUITE_FAILURE: case TEST_IGNORED_ASSUMPTION: case TEST_IGNORED: case TEST_STARTED: case TEST_FINISHED: case TEST_FAILURE: flushBoth(output, out, err, stdout, stderr); marker = new JsonObject(); marker.addProperty("event", evt.getType().toString()); marker.add("description", context.serialize(((IDescribable) evt).getDescription())); if (evt instanceof FailureEvent) { marker.add("failure", context.serialize(((FailureEvent) evt).getFailure())); } output.add(marker); break; // Flush streams only if there's interwoven output between them. case APPEND_STDOUT: if (outputStreams) { flush(APPEND_STDERR, output, stderr, err); ((IStreamEvent) evt).copyTo(stdout); } break; case APPEND_STDERR: if (outputStreams) { flush(APPEND_STDOUT, output, stdout, out); ((IStreamEvent) evt).copyTo(stderr); } break; default: break; } } catch (IOException ex) { // Ignore. } } flushBoth(output, out, err, stdout, stderr); return output; } public void flushBoth(JsonArray output, final StringWriter out, final StringWriter err, WriterOutputStream stdout, WriterOutputStream stderr) { try { flush(APPEND_STDOUT, output, stdout, out); flush(APPEND_STDERR, output, stderr, err); } catch (IOException ex) { // Ignore. } } private void flush(EventType evt, JsonArray output, WriterOutputStream wos, StringWriter out) throws IOException { wos.flush(); if (out.getBuffer().length() > 0) { JsonObject chunk = new JsonObject(); chunk.addProperty("event", evt.toString()); chunk.addProperty("content", out.getBuffer().toString()); out.getBuffer().setLength(0); output.add(chunk); } } } JsonAggregatedTestResultEventAdapter.java000066400000000000000000000020231235451432000446720ustar00rootroot00000000000000randomizedtesting-release-2.1.6/junit4-ant/src/main/java/com/carrotsearch/ant/tasks/junit4/listeners/jsonpackage com.carrotsearch.ant.tasks.junit4.listeners.json; import java.lang.reflect.Type; import java.util.Date; import com.carrotsearch.ant.tasks.junit4.events.aggregated.AggregatedTestResultEvent; import com.google.gson.*; /** * Serialization of {@link AggregatedTestResultEvent}. */ public class JsonAggregatedTestResultEventAdapter implements JsonSerializer { @Override public JsonElement serialize(AggregatedTestResultEvent e, Type type, JsonSerializationContext context) { JsonObject suite = new JsonObject(); suite.addProperty("slave", e.getSlave().id); suite.addProperty("startTimestamp", e.getStartTimestamp()); suite.add("startTimestampDate", context.serialize(new Date(e.getStartTimestamp()))); suite.addProperty("executionTime", e.getExecutionTime()); suite.add("description", context.serialize(e.getDescription())); suite.addProperty("status", e.getStatus().name()); suite.add("testFailures", context.serialize(e.getFailures())); return suite; } } JsonFailureMirrorAdapter.java000066400000000000000000000020141235451432000423610ustar00rootroot00000000000000randomizedtesting-release-2.1.6/junit4-ant/src/main/java/com/carrotsearch/ant/tasks/junit4/listeners/jsonpackage com.carrotsearch.ant.tasks.junit4.listeners.json; import java.lang.reflect.Type; import com.carrotsearch.ant.tasks.junit4.events.mirrors.FailureMirror; import com.google.gson.*; /** * Serialization of {@link FailureMirror}. */ public class JsonFailureMirrorAdapter implements JsonSerializer { @Override public JsonElement serialize(FailureMirror e, Type type, JsonSerializationContext context) { JsonObject object = new JsonObject(); object.addProperty("throwableClass", e.getThrowableClass()); object.addProperty("throwableString", e.getThrowableString()); object.addProperty("stackTrace", e.getTrace()); String throwableKind; if (e.isAssertionViolation()) { throwableKind = "assertion"; } else if (e.isErrorViolation()) { throwableKind = "error"; } else if (e.isAssumptionViolation()) { throwableKind = "assumption"; } else { throwableKind = "unknown"; } object.addProperty("kind", throwableKind); return object; } } JsonReport.java000066400000000000000000000214371235451432000375630ustar00rootroot00000000000000randomizedtesting-release-2.1.6/junit4-ant/src/main/java/com/carrotsearch/ant/tasks/junit4/listeners/jsonpackage com.carrotsearch.ant.tasks.junit4.listeners.json; import java.io.*; import java.lang.annotation.Annotation; import java.net.URL; import java.util.Locale; import java.util.Map; import java.util.regex.Pattern; import org.apache.commons.io.FilenameUtils; import org.apache.tools.ant.BuildException; import org.apache.tools.ant.Project; import org.junit.runner.Description; import com.carrotsearch.ant.tasks.junit4.JUnit4; import com.carrotsearch.ant.tasks.junit4.ForkedJvmInfo; import com.carrotsearch.ant.tasks.junit4.events.aggregated.*; import com.carrotsearch.ant.tasks.junit4.events.json.*; import com.carrotsearch.ant.tasks.junit4.events.mirrors.FailureMirror; import com.carrotsearch.ant.tasks.junit4.listeners.AggregatedEventListener; import com.google.common.base.*; import com.google.common.collect.Maps; import com.google.common.eventbus.Subscribe; import com.google.common.io.Files; import com.google.common.io.Resources; import com.google.gson.Gson; import com.google.gson.GsonBuilder; import com.google.gson.stream.JsonWriter; /** * A report listener that produces a single JSON file for all suites and tests. */ public class JsonReport implements AggregatedEventListener { private JUnit4 junit4; private File targetFile; private String jsonpMethod; private JsonWriter jsonWriter; private Gson gson; private String projectName; private Map slaves = Maps.newTreeMap(); private OutputStreamWriter writer; private static enum OutputMethod { JSON, JSONP, HTML } /** * How should the report be written? */ private OutputMethod method; /** * @see #setOutputStreams(boolean) */ private boolean outputStreams = true; /** * Output file for the report file. The name of the output file * will also trigger how the report is written. If the name of the * output file ends with ".htm(l)?" then the output file is a HTML * file and CSS/JS scaffolding is also written to visualize the JSON * model. * * If the name of the file ends with ".json(p)?" a JSON file is written. */ public void setFile(File file) { String fileName = file.getName().toLowerCase(Locale.ENGLISH); if (fileName.matches(".*\\.htm(l)?$")) { method = OutputMethod.HTML; } else { if (fileName.matches(".*\\.jsonp")) { method = OutputMethod.JSONP; } else { method = OutputMethod.JSON; } } this.targetFile = file; } /** * Sets wrapper method name for JSONP. If set to non-empty * value, will change the output format to JSONP. The name of the * JSONP function for the HTML wrapper must be "testData". * * @see "http://en.wikipedia.org/wiki/JSONP" */ public void setJsonpMethod(String method) { this.jsonpMethod = Strings.emptyToNull(method); } /** * Set project name for the output model. */ public void setProjectName(String projectName) { this.projectName = projectName; } /** * Include output streams? Mind that with large outputs the report may OOM. */ public void setOutputStreams(boolean outputStreams) { this.outputStreams = outputStreams; } /* * */ @Override public void setOuter(JUnit4 junit4) { this.junit4 = junit4; if (this.targetFile == null) { throw new BuildException("'file' attribute is required (target file name ending in .html, .json or .jsonp)."); } if (method == OutputMethod.HTML) { if (Strings.isNullOrEmpty(jsonpMethod)) { setJsonpMethod("testData"); } else if (!"testData".equals(jsonpMethod)) { throw new BuildException("JSONP method must be empty or equal 'testData' for HTML output."); } } if (method == OutputMethod.JSONP) { if (Strings.isNullOrEmpty(jsonpMethod)) { setJsonpMethod("testData"); } } final ClassLoader refLoader = Thread.currentThread().getContextClassLoader(); this.gson = new GsonBuilder() .registerTypeAdapter(AggregatedSuiteResultEvent.class, new JsonAggregatedSuiteResultEventAdapter(outputStreams)) .registerTypeAdapter(AggregatedTestResultEvent.class, new JsonAggregatedTestResultEventAdapter()) .registerTypeAdapter(FailureMirror.class, new JsonFailureMirrorAdapter()) .registerTypeAdapter(ForkedJvmInfo.class, new JsonSlaveInfoAdapter()) .registerTypeHierarchyAdapter(Annotation.class, new JsonAnnotationAdapter(refLoader)) .registerTypeHierarchyAdapter(Class.class, new JsonClassAdapter(refLoader)) .registerTypeAdapter(Description.class, new JsonDescriptionAdapter()) .setDateFormat("yyyy-MM-dd'T'HH:mm:ss.SSS") .setPrettyPrinting().create(); try { Files.createParentDirs(targetFile); File jsonFile = targetFile; if (method == OutputMethod.HTML) { jsonFile = new File(FilenameUtils.removeExtension(targetFile.getAbsolutePath()) + ".jsonp"); } writer = new OutputStreamWriter( new BufferedOutputStream(new FileOutputStream(jsonFile)),Charsets.UTF_8); if (!Strings.isNullOrEmpty(jsonpMethod)) { writer.write(jsonpMethod); writer.write("("); } jsonWriter = new JsonWriter(writer); jsonWriter.setHtmlSafe(false); jsonWriter.setIndent(" "); jsonWriter.beginObject(); // Main holder. // junit4 object with properties. jsonWriter.name("junit4"); jsonWriter.beginObject(); jsonWriter.name("tests.seed"); jsonWriter.value(junit4.getSeed()); jsonWriter.name("project.name"); jsonWriter.value(getProjectName()); jsonWriter.endObject(); // suites and an array of suites follows. jsonWriter.name("suites"); jsonWriter.beginArray(); } catch (IOException e) { throw new BuildException("Could not emit JSON report.", e); } } /** * Return the project name or the default project name. */ private String getProjectName() { String pName = Strings.emptyToNull(projectName); if (pName == null) { pName = Strings.emptyToNull(junit4.getProject().getName()); } if (pName == null) { pName = "(unnamed project)"; } return pName; } /** * Emit information about a single suite and all of its tests. */ @Subscribe public void onSuiteResult(AggregatedSuiteResultEvent e) { try { if (gson == null) return; slaves.put(e.getSlave().id, e.getSlave()); gson.toJson(e, e.getClass(), jsonWriter); } catch (Exception ex) { ex.printStackTrace(); junit4.log("Error serializing to JSON file: " + Throwables.getStackTraceAsString(ex), Project.MSG_WARN); gson = null; } } /** * All tests completed. */ @Subscribe public void onQuit(AggregatedQuitEvent e) { if (gson == null) return; try { jsonWriter.endArray(); jsonWriter.name("slaves"); gson.toJson(slaves, slaves.getClass(), jsonWriter); jsonWriter.endObject(); jsonWriter.flush(); if (!Strings.isNullOrEmpty(jsonpMethod)) { writer.write(");"); } jsonWriter.close(); jsonWriter = null; writer = null; if (method == OutputMethod.HTML) { copyScaffolding(targetFile); } } catch (IOException x) { junit4.log(x, Project.MSG_ERR); } } /** * Copy HTML/JS/CSS scaffolding to a targetFile's directory. */ private void copyScaffolding(File targetFile) throws IOException { String resourcePrefix = "com/carrotsearch/ant/tasks/junit4/templates/json/"; File parent = targetFile.getParentFile(); // Handle index.html substitutitons. ClassLoader cl = this.getClass().getClassLoader(); String index = Resources.toString( cl.getResource(resourcePrefix + "index.html"), Charsets.UTF_8); index = index.replaceAll(Pattern.quote("tests-output.jsonp"), FilenameUtils.removeExtension(targetFile.getName()) + ".jsonp"); Files.write(index, targetFile, Charsets.UTF_8); // Copy over the remaining files. This is hard coded but scanning a JAR seems like an overkill. String [] resources = { "js/jquery-1.7.1.min.js", "js/script.js", "js/jquery.pathchange.js", "img/pass.png", "img/error.png", "img/stderr.png", "img/arrow-up.png", "img/stdout.png", "img/indicator.png", "img/failure.png", "img/omited.png", "img/arrow-down.png", "css/style.css" }; for (String resource : resources) { File target = new File(parent, resource); if (!target.getParentFile().exists()) { target.getParentFile().mkdirs(); } URL res = cl.getResource(resourcePrefix + resource); if (res == null) { throw new IOException("Could not find the required report resource: " + resource); } Files.write(Resources.toByteArray(res), target); } } } JsonSlaveInfoAdapter.java000066400000000000000000000014101235451432000414640ustar00rootroot00000000000000randomizedtesting-release-2.1.6/junit4-ant/src/main/java/com/carrotsearch/ant/tasks/junit4/listeners/jsonpackage com.carrotsearch.ant.tasks.junit4.listeners.json; import java.lang.reflect.Type; import com.carrotsearch.ant.tasks.junit4.ForkedJvmInfo; import com.google.gson.*; /** * Serialization of {@link ForkedJvmInfo}. */ public class JsonSlaveInfoAdapter implements JsonSerializer { @Override public JsonElement serialize(ForkedJvmInfo e, Type type, JsonSerializationContext context) { JsonObject object = new JsonObject(); object.addProperty("id", e.id); object.addProperty("jvmName", e.getJvmName()); object.addProperty("charset", e.getCharset().displayName()); object.addProperty("commandLine", e.getCommandLine()); object.add("systemProperties", context.serialize(e.getSystemProperties())); return object; } } package.html000066400000000000000000000030151235451432000341030ustar00rootroot00000000000000randomizedtesting-release-2.1.6/junit4-ant/src/main/java/com/carrotsearch/ant/tasks/junit4 Randomized Testing: Randomized Runner Provides {@link com.carrotsearch.ant.tasks.junit4.JUnit4}: a JUnit test runner for ANT with parallel slave JVM execution, load balancing and more reporting options.

See {@link com.carrotsearch.ant.tasks.junit4.JUnit4} for the documentation of available task options.

Listeners and reporters API is covered in {@link com.carrotsearch.ant.tasks.junit4.listeners.AggregatedEventListener} class. Note that the API is event-based and uses Google Guava's {@link com.google.common.eventbus.EventBus} to distribute events. Check out existing reporters for implementation details:

  • {@link com.carrotsearch.ant.tasks.junit4.listeners.TextReport}
  • {@link com.carrotsearch.ant.tasks.junit4.listeners.antxml.AntXmlReport}
  • {@link com.carrotsearch.ant.tasks.junit4.listeners.json.JsonReport}
  • {@link com.carrotsearch.ant.tasks.junit4.listeners.ExecutionTimesReport}

Examples of use and more resources can be found at: Carrot Search labs site.

randomizedtesting-release-2.1.6/junit4-ant/src/main/java/com/carrotsearch/ant/tasks/junit4/slave/000077500000000000000000000000001235451432000330145ustar00rootroot00000000000000BeforeAfterRunListenerDecorator.java000066400000000000000000000036671235451432000420360ustar00rootroot00000000000000randomizedtesting-release-2.1.6/junit4-ant/src/main/java/com/carrotsearch/ant/tasks/junit4/slavepackage com.carrotsearch.ant.tasks.junit4.slave; import java.lang.reflect.Proxy; import org.junit.runner.Description; import org.junit.runner.Result; import org.junit.runner.notification.Failure; import org.junit.runner.notification.RunListener; /** * {@link RunListener} decorator that does something before and after a given method call. * A fancier impl. could use a {@link Proxy} but {@link RunListener} is not an interface. */ public abstract class BeforeAfterRunListenerDecorator extends RunListener { private final RunListener delegate; public BeforeAfterRunListenerDecorator(RunListener delegate) { this.delegate = delegate; } public final void testRunStarted(Description description) throws Exception { before(); try { delegate.testRunStarted(description); } finally { after(); } } public final void testRunFinished(Result result) throws Exception { before(); try { delegate.testRunFinished(result); } finally { after(); } } public final void testStarted(Description description) throws Exception { before(); try { delegate.testStarted(description); } finally { after(); } } public final void testFinished(Description description) throws Exception { before(); try { delegate.testFinished(description); } finally { after(); } } public final void testFailure(Failure failure) throws Exception { before(); try { delegate.testFailure(failure); } finally { after(); } } public final void testAssumptionFailure(Failure failure) { before(); try { delegate.testAssumptionFailure(failure); } finally { after(); } } public final void testIgnored(Description description) throws Exception { before(); try { delegate.testIgnored(description); } finally { after(); } } protected void after() {} protected void before() {} } EventsOutputStream.java000066400000000000000000000014411235451432000374410ustar00rootroot00000000000000randomizedtesting-release-2.1.6/junit4-ant/src/main/java/com/carrotsearch/ant/tasks/junit4/slavepackage com.carrotsearch.ant.tasks.junit4.slave; import java.io.*; /** * An OutputStream delegate. */ class EventsOutputStream extends OutputStream { private OutputStream os; public EventsOutputStream(File file) throws IOException { final int bufferSize = 8 * 1024; this.os = new BufferedOutputStream(new FileOutputStream(file), bufferSize); } @Override public void write(int b) throws IOException { os.write(b); } @Override public void write(byte[] b) throws IOException { os.write(b); } @Override public void write(byte[] b, int off, int len) throws IOException { os.write(b, off, len); } @Override public void flush() throws IOException { os.flush(); } @Override public void close() throws IOException { os.close(); } } JvmExit.java000066400000000000000000000011531235451432000351660ustar00rootroot00000000000000randomizedtesting-release-2.1.6/junit4-ant/src/main/java/com/carrotsearch/ant/tasks/junit4/slavepackage com.carrotsearch.ant.tasks.junit4.slave; final class JvmExit { final static void halt(final int code) { // try to exit gracefully by calling system.exit. If we terminate within 5 seconds, fine. // If not, halt the JVM. final Thread exiter = new Thread() { @Override public void run() { System.exit(code); } }; long deadline = System.currentTimeMillis() + 5 * 1000; exiter.start(); try { while (System.currentTimeMillis() < deadline) { Thread.sleep(500); } } catch (Throwable t) {} Runtime.getRuntime().halt(code); } } NoExceptionRunListenerDecorator.java000066400000000000000000000037051235451432000420760ustar00rootroot00000000000000randomizedtesting-release-2.1.6/junit4-ant/src/main/java/com/carrotsearch/ant/tasks/junit4/slavepackage com.carrotsearch.ant.tasks.junit4.slave; import java.lang.reflect.Proxy; import org.junit.runner.Description; import org.junit.runner.Result; import org.junit.runner.notification.Failure; import org.junit.runner.notification.RunListener; /** * {@link RunListener} decorator that does something before and after a given method call. * A fancier impl. could use a {@link Proxy} but {@link RunListener} is not an interface. */ public abstract class NoExceptionRunListenerDecorator extends RunListener { private final RunListener delegate; public NoExceptionRunListenerDecorator(RunListener delegate) { this.delegate = delegate; } public final void testRunStarted(Description description) throws Exception { try { delegate.testRunStarted(description); } catch (Throwable t) { exception(t); } } public final void testRunFinished(Result result) throws Exception { try { delegate.testRunFinished(result); } catch (Throwable t) { exception(t); } } public final void testStarted(Description description) throws Exception { try { delegate.testStarted(description); } catch (Throwable t) { exception(t); } } public final void testFinished(Description description) throws Exception { try { delegate.testFinished(description); } catch (Throwable t) { exception(t); } } public final void testFailure(Failure failure) throws Exception { try { delegate.testFailure(failure); } catch (Throwable t) { exception(t); } } public final void testAssumptionFailure(Failure failure) { try { delegate.testAssumptionFailure(failure); } catch (Throwable t) { exception(t); } } public final void testIgnored(Description description) throws Exception { try { delegate.testIgnored(description); } catch (Throwable t) { exception(t); } } protected abstract void exception(Throwable t); } NullWriter.java000066400000000000000000000005641235451432000357140ustar00rootroot00000000000000randomizedtesting-release-2.1.6/junit4-ant/src/main/java/com/carrotsearch/ant/tasks/junit4/slavepackage com.carrotsearch.ant.tasks.junit4.slave; import java.io.IOException; import java.io.Writer; final class NullWriter extends Writer { @Override public void write(char[] cbuf, int off, int len) throws IOException { } @Override public void flush() throws IOException { } @Override public void close() throws IOException { } } OrderedRunNotifier.java000066400000000000000000000123531235451432000373550ustar00rootroot00000000000000randomizedtesting-release-2.1.6/junit4-ant/src/main/java/com/carrotsearch/ant/tasks/junit4/slavepackage com.carrotsearch.ant.tasks.junit4.slave; import java.util.*; import org.junit.internal.AssumptionViolatedException; import org.junit.runner.Description; import org.junit.runner.Result; import org.junit.runner.notification.*; public class OrderedRunNotifier extends RunNotifier { /** * A linked list is more convenient for descending iterators. */ private final LinkedList listeners = new LinkedList(); private volatile boolean stopRequested = false; /** * Add a listener at the end of the listener list. */ public void addListener(RunListener listener) { synchronized (listeners) { listeners.add(listener); } } /** * Adds a listener at the head of the listener list. */ public void addFirstListener(RunListener listener) { synchronized (listeners) { listeners.addFirst(listener); } } /** * Remove a listener from the listener list. */ public void removeListener(RunListener listener) { synchronized (listeners) { listeners.remove(listener); } } /** * Notify listeners in the requested order */ private abstract class SafeNotifier { void run() { run(false); } void run(boolean reversedOrder) { synchronized (listeners) { final Iterator i; if (reversedOrder) { i = listeners.descendingIterator(); } else { i = listeners.iterator(); } while (i.hasNext()) { try { notifyListener(i.next()); } catch (Exception e) { i.remove(); // Remove the offending listener. fireTestFailure(new Failure(Description.TEST_MECHANISM, e)); } } } } abstract protected void notifyListener(RunListener each) throws Exception; } /** * Do not invoke. */ public void fireTestRunStarted(final Description description) { new SafeNotifier() { @Override protected void notifyListener(RunListener each) throws Exception { each.testRunStarted(description); }; }.run(); } /** * Do not invoke. */ public void fireTestRunFinished(final Result result) { new SafeNotifier() { @Override protected void notifyListener(RunListener each) throws Exception { each.testRunFinished(result); }; }.run(true); } /** * Invoke to tell listeners that an atomic test is about to start. * * @param description * the description of the atomic test (generally a class and method * name) * @throws StoppedByUserException * thrown if a user has requested that the test run stop */ public void fireTestStarted(final Description description) throws StoppedByUserException { if (stopRequested) throw new StoppedByUserException(); new SafeNotifier() { @Override protected void notifyListener(RunListener each) throws Exception { each.testStarted(description); }; }.run(); } /** * Invoke to tell listeners that an atomic test failed. * * @param failure * the description of the test that failed and the exception thrown */ public void fireTestFailure(final Failure failure) { new SafeNotifier() { @Override protected void notifyListener(RunListener each) throws Exception { each.testFailure(failure); }; }.run(true); } /** * Invoke to tell listeners that an atomic test flagged that it assumed * something false. * * @param failure * the description of the test that failed and the * {@link AssumptionViolatedException} thrown */ public void fireTestAssumptionFailed(final Failure failure) { new SafeNotifier() { @Override protected void notifyListener(RunListener each) throws Exception { each.testAssumptionFailure(failure); }; }.run(true); } /** * Invoke to tell listeners that an atomic test was ignored. * * @param description * the description of the ignored test */ public void fireTestIgnored(final Description description) { new SafeNotifier() { @Override protected void notifyListener(RunListener each) throws Exception { each.testIgnored(description); } }.run(true); } /** * Invoke to tell listeners that an atomic test finished. Always invoke * {@link #fireTestFinished(Description)} if you invoke * {@link #fireTestStarted(Description)} as listeners are likely to expect * them to come in pairs. * * @param description * the description of the test that finished */ public void fireTestFinished(final Description description) { new SafeNotifier() { @Override protected void notifyListener(RunListener each) throws Exception { each.testFinished(description); }; }.run(true); } /** * Ask that the tests run stop before starting the next test. Phrased politely * because the test currently running will not be interrupted. It seems a * little odd to put this functionality here, but the RunNotifier * is the only object guaranteed to be shared amongst the many runners * involved. */ public void pleaseStop() { stopRequested = true; } } RunListenerEmitter.java000066400000000000000000000100121235451432000373760ustar00rootroot00000000000000randomizedtesting-release-2.1.6/junit4-ant/src/main/java/com/carrotsearch/ant/tasks/junit4/slavepackage com.carrotsearch.ant.tasks.junit4.slave; import java.io.IOException; import org.junit.Ignore; import org.junit.runner.Description; import org.junit.runner.Result; import org.junit.runner.notification.Failure; import org.junit.runner.notification.RunListener; import com.carrotsearch.ant.tasks.junit4.events.*; /** * Serialize test execution events. Attempts to handle * certain corner cases that are not cleanly handled by * JUnit itself (reporting the cause of ignored methods, * etc.). */ public class RunListenerEmitter extends RunListener { private final Serializer serializer; private Description suiteDescription; private long start; private long suiteStart; /** * A failure signaled at the suite level. Most likely will result * in ignored methods. */ private Failure suiteAssumption; public RunListenerEmitter(Serializer serializer) { this.serializer = serializer; } @Override public void testRunStarted(Description description) throws Exception { this.suiteDescription = description; this.suiteStart = System.currentTimeMillis(); this.suiteAssumption = null; serializer.serialize(new SuiteStartedEvent(description, suiteStart)); } @Override public void testStarted(Description description) throws Exception { serializer.serialize(new TestStartedEvent(description)); start = System.currentTimeMillis(); } @Override public void testFailure(Failure failure) throws Exception { if (suiteDescription.equals(failure.getDescription())) { serializer.serialize(new SuiteFailureEvent(failure)); } else { serializer.serialize(new TestFailureEvent(failure)); } } @Override public void testAssumptionFailure(Failure failure) { try { // Check for class-level assumption failures that may result // in message-less ignored tests. See GH-103. if (suiteDescription != null && suiteDescription.equals(failure.getDescription())) { suiteAssumption = failure; } serializer.serialize(new TestIgnoredAssumptionEvent(failure)); } catch (IOException e) { throw new RuntimeException(e); } } @Override public void testIgnored(Description description) throws Exception { if (suiteDescription.equals(description)) { // JUnitCore has built-in precedence of runners and handles @Ignore // with a different runner, regardless of what is declared in @RunWith. This is // bad. } else { // GH-82: try to determine the reason why the test has been ignored and populate // the cause message. This really should be passed from the runner but the API does // not allow it. String cause = "Unknown reason for ignore status."; // GH-103: check suite-level assumptions. if (suiteAssumption != null) { String msg = suiteAssumption.getMessage(); cause = (msg != null ? msg : "Class assumption-ignored."); } try { Ignore ignoreAnn = description.getAnnotation(Ignore.class); if ((ignoreAnn = description.getAnnotation(Ignore.class)) != null) { cause = "Annotated @Ignore(" + ignoreAnn.value() + ")"; } else { // Try class. ignoreAnn = description.getTestClass().getAnnotation(Ignore.class); if (ignoreAnn != null) { cause = "Class annotated @Ignore(" + ignoreAnn.value() + ")"; } } } catch (Throwable t) { // Never fail on this. } serializer.serialize(new TestIgnoredEvent(description, cause)); } } @Override public void testFinished(Description description) throws Exception { long executionTime = System.currentTimeMillis() - start; serializer.serialize(new TestFinishedEvent(description, (int) executionTime, start)); } @Override public void testRunFinished(Result result) throws Exception { suiteAssumption = null; final long duration = System.currentTimeMillis() - suiteStart; serializer.serialize( new SuiteCompletedEvent(suiteDescription, suiteStart, duration)); } } SlaveMain.java000066400000000000000000000336631235451432000354720ustar00rootroot00000000000000randomizedtesting-release-2.1.6/junit4-ant/src/main/java/com/carrotsearch/ant/tasks/junit4/slavepackage com.carrotsearch.ant.tasks.junit4.slave; import java.io.*; import java.util.*; import org.junit.runner.*; import org.junit.runner.manipulation.Filter; import org.junit.runner.manipulation.NoTestsRemainException; import org.junit.runner.notification.*; import com.carrotsearch.ant.tasks.junit4.events.*; import com.carrotsearch.randomizedtesting.MethodGlobFilter; import com.carrotsearch.randomizedtesting.SysGlobals; import com.google.common.base.Strings; import com.google.common.base.Throwables; import com.google.common.collect.Iterators; import com.google.common.collect.Lists; /** * A slave process running the actual tests on the target JVM. */ public class SlaveMain { /** Runtime exception. */ public static final int ERR_EXCEPTION = 240; /** No JUnit on classpath. */ public static final int ERR_NO_JUNIT = 239; /** Old JUnit on classpath. */ public static final int ERR_OLD_JUNIT = 238; /** OOM */ public static final int ERR_OOM = 237; /** * Last resort memory pool released under low memory conditions. * This is not a solution, it's a terrible hack. I know this. Everyone knows this. * Even monkeys in Madagaskar know this. If you know a better solution, patches * welcome. * *

Approximately 5mb is reserved. Really, smaller values don't make any difference * and the JVM fails to even return the status passed to Runtime.halt(). */ static volatile Object lastResortMemory = new byte [1024 * 1024 * 5]; /** * Preallocate and load in advance. */ static Class oomClass = OutOfMemoryError.class; /** * Frequent event strean flushing. */ public static final String OPTION_FREQUENT_FLUSH = "-flush"; /** * Multiplex sysout and syserr to original streams (aside from * pumping them to event stream). */ public static final String OPTION_SYSOUTS = "-sysouts"; /** * Read class names from standard input. */ public static final String OPTION_STDIN = "-stdin"; /** * Name the sink for events. If given, accepts one argument - name of a file * to which events should be dumped. The file has to be initially empty! */ public static final String OPTION_EVENTSFILE = "-eventsfile"; /** * Should the debug stream from the runner be created? It's named after the events file * with .debug suffix. */ public static final String OPTION_DEBUGSTREAM = "-debug"; /** * Fire a runner failure after startup to verify messages * are propagated properly. Not really useful in practice... */ public static final String SYSPROP_FIRERUNNERFAILURE = SlaveMain.class.getName() + ".fireRunnerFailure"; /** * Event sink. */ private final Serializer serializer; /** A sink for warnings (non-event stream). */ private static PrintStream warnings; /** Flush serialization stream frequently. */ private boolean flushFrequently = false; /** Debug stream to flush progress information to. */ private File debugMessagesFile; /** * Multiplex calls to System streams to both event stream * and the original streams? */ private static boolean multiplexStdStreams = false; /** * Base for redirected streams. */ private static class ChunkedStream extends OutputStream { public void write(int b) throws IOException { throw new IOException("Only buffered write(byte[],int,int) calls expected from super stream."); } @Override public void close() throws IOException { throw new IOException("Not supposed to be called on redirected streams."); } } /** * Creates a slave emitting events to the given serializer. */ public SlaveMain(Serializer serializer) { this.serializer = serializer; } /** * Execute tests. */ private void execute(Iterator classNames) throws Throwable { final RunNotifier fNotifier = new OrderedRunNotifier(); final Result result = new Result(); final Writer debug = debugMessagesFile == null ? new NullWriter() : new OutputStreamWriter(new FileOutputStream(debugMessagesFile), "UTF-8"); fNotifier.addListener(result.createListener()); fNotifier.addListener( new StreamFlusherDecorator( new NoExceptionRunListenerDecorator(new RunListenerEmitter(serializer)) { @Override protected void exception(Throwable t) { warn("Event serializer exception.", t); } })); fNotifier.addListener(new RunListener() { public void testRunFinished(Result result) throws Exception { debug(debug, "testRunFinished(T:" + result.getRunCount() + ";F:" + result.getFailureCount() + ";I:" + result.getIgnoreCount() + ")"); serializer.flush(); } @Override public void testRunStarted(Description description) throws Exception { debug(debug, "testRunStarted(" + description + ")"); serializer.flush(); } @Override public void testStarted(Description description) throws Exception { debug(debug, "testStarted(" + description + ")"); serializer.flush(); } public void testFinished(Description description) throws Exception { debug(debug, "testFinished(" + description + ")"); serializer.flush(); } }); /* * Instantiate method filter if any. */ String methodFilterGlob = Strings.emptyToNull(System.getProperty(SysGlobals.SYSPROP_TESTMETHOD())); Filter methodFilter = Filter.ALL; if (methodFilterGlob != null) { methodFilter = new MethodGlobFilter(methodFilterGlob); } /* * Important. Run each class separately so that we get separate * {@link RunListener} callbacks for the top extracted description. */ debug(debug, "Entering main suite loop."); try { while (classNames.hasNext()) { final String clName = classNames.next(); debug(debug, "Instantiating: " + clName); Class clazz = instantiate(clName); if (clazz == null) continue; Request request = Request.aClass(clazz); try { Runner runner = request.getRunner(); methodFilter.apply(runner); fNotifier.fireTestRunStarted(runner.getDescription()); debug(debug, "Runner.run(" + clName + ")"); runner.run(fNotifier); debug(debug, "Runner.done(" + clName + ")"); fNotifier.fireTestRunFinished(result); } catch (NoTestsRemainException e) { // Don't complain if all methods have been filtered out. // I don't understand the reason why this exception has been // built in to filters at all. } } } catch (Throwable t) { debug(debug, "Main suite loop error: " + t); throw t; } finally { debug(debug, "Leaving main suite loop."); debug.close(); } } private void debug(Writer w, String msg) throws IOException { w.write(msg); w.write("\n"); w.flush(); } /** * Instantiate test classes (or try to). */ private Class instantiate(String className) { try { return Class.forName(className, false, Thread.currentThread().getContextClassLoader()); } catch (Throwable t) { try { serializer.serialize( new SuiteFailureEvent( new Failure(Description.createSuiteDescription(className), t))); if (flushFrequently) serializer.flush(); } catch (Exception e) { warn("Could not report failure back to master.", t); } return null; } } /** * Console entry point. */ @SuppressWarnings("resource") public static void main(String[] allArgs) { int exitStatus = 0; Serializer serializer = null; try { final ArrayDeque args = new ArrayDeque(Arrays.asList(allArgs)); // Options. boolean debugStream = false; boolean flushFrequently = false; File eventsFile = null; boolean suitesOnStdin = false; List testClasses = Lists.newArrayList(); while (!args.isEmpty()) { String option = args.pop(); if (option.equals(OPTION_FREQUENT_FLUSH)) { flushFrequently = true; } else if (option.equals(OPTION_STDIN)) { suitesOnStdin = true; } else if (option.equals(OPTION_SYSOUTS)) { multiplexStdStreams = true; } else if (option.equals(OPTION_EVENTSFILE)) { eventsFile = new File(args.pop()); if (eventsFile.isFile() && eventsFile.length() > 0) { RandomAccessFile raf = new RandomAccessFile(eventsFile, "rw"); raf.setLength(0); raf.close(); } } else if (option.startsWith(OPTION_DEBUGSTREAM)) { debugStream = true; } else if (option.startsWith("@")) { // Append arguments file, one line per option. args.addAll(Arrays.asList(readArgsFile(option.substring(1)))); } else { // The default expectation is a test class. testClasses.add(option); } } // Set up events channel and events serializer. if (eventsFile == null) { throw new IOException("You must specify communication channel for events."); } // Send bootstrap package. serializer = new Serializer(new EventsOutputStream(eventsFile)) .serialize(new BootstrapEvent()) .flush(); // Redirect original streams and start running tests. redirectStreams(serializer, flushFrequently); final SlaveMain main = new SlaveMain(serializer); main.flushFrequently = flushFrequently; main.debugMessagesFile = debugStream ? new File(eventsFile.getAbsolutePath() + ".debug"): null; final Iterator stdInput; if (suitesOnStdin) { stdInput = new StdInLineIterator(main.serializer); } else { stdInput = Collections.emptyList().iterator(); } main.execute(Iterators.concat(testClasses.iterator(), stdInput)); // For unhandled exceptions tests. if (System.getProperty(SYSPROP_FIRERUNNERFAILURE) != null) { throw new Exception(System.getProperty(SYSPROP_FIRERUNNERFAILURE)); } } catch (Throwable t) { lastResortMemory = null; tryWaitingForGC(); if (t.getClass() == oomClass) { exitStatus = ERR_OOM; warn("JVM out of memory.", t); } else { exitStatus = ERR_EXCEPTION; warn("Exception at main loop level.", t); } } try { if (serializer != null) { try { serializer.close(); } catch (Throwable t) { warn("Exception closing serializer.", t); } } } finally { JvmExit.halt(exitStatus); } } /** * Try waiting for a GC to happen. This is a dirty heuristic but if we're * here we're neck deep in sh*t anyway (OOMs all over). */ private static void tryWaitingForGC() { // TODO: we could try to preallocate memory mx bean and count collections. // there is no guarantee it doesn't allocate stuff too though. final long timeout = System.currentTimeMillis() + 2000; while (System.currentTimeMillis() < timeout) { System.gc(); try { Thread.sleep(250); } catch (InterruptedException e) { break; } } } /** * Read arguments from a file. Newline delimited, UTF-8 encoded. No fanciness to * avoid dependencies. */ private static String[] readArgsFile(String argsFile) throws IOException { final ArrayList lines = new ArrayList(); final BufferedReader reader = new BufferedReader( new InputStreamReader( new FileInputStream(argsFile), "UTF-8")); try { String line; while ((line = reader.readLine()) != null) { line = line.trim(); if (!line.isEmpty() && !line.startsWith("#")) { lines.add(line); } } } finally { reader.close(); } return lines.toArray(new String [lines.size()]); } /** * Redirect standard streams so that the output can be passed to listeners. */ private static void redirectStreams(final Serializer serializer, final boolean flushFrequently) { final PrintStream origSysOut = System.out; final PrintStream origSysErr = System.err; // Set warnings stream to System.err. warnings = System.err; System.setOut(new PrintStream(new BufferedOutputStream(new ChunkedStream() { @Override public void write(byte[] b, int off, int len) throws IOException { if (multiplexStdStreams) { origSysOut.write(b, off, len); } serializer.serialize(new AppendStdOutEvent(b, off, len)); if (flushFrequently) serializer.flush(); } }))); System.setErr(new PrintStream(new BufferedOutputStream(new ChunkedStream() { @Override public void write(byte[] b, int off, int len) throws IOException { if (multiplexStdStreams) { origSysErr.write(b, off, len); } serializer.serialize(new AppendStdErrEvent(b, off, len)); if (flushFrequently) serializer.flush(); } }))); } /** * Warning emitter. Uses whatever alternative non-event communication channel is. */ public static void warn(String message, Throwable t) { @SuppressWarnings("resource") PrintStream w = (warnings == null ? System.err : warnings); try { w.print("WARN: "); w.print(message); if (t != null) { w.print(" -> "); try { w.println(Throwables.getStackTraceAsString(t)); } catch (OutOfMemoryError e) { // Ignore, OOM. w.print(t.getClass().getName()); w.print(": "); w.print(t.getMessage()); w.println(" (stack unavailable; OOM)"); } } else { w.println(); } w.flush(); } catch (OutOfMemoryError t2) { w.println("ERROR: Couldn't even serialize a warning (out of memory)."); } catch (Throwable t2) { // Can't do anything, really. Probably an OOM? w.println("ERROR: Couldn't even serialize a warning."); } } } SlaveMainSafe.java000066400000000000000000000015501235451432000362570ustar00rootroot00000000000000randomizedtesting-release-2.1.6/junit4-ant/src/main/java/com/carrotsearch/ant/tasks/junit4/slavepackage com.carrotsearch.ant.tasks.junit4.slave; import java.io.PrintStream; import java.io.Serializable; public class SlaveMainSafe { public static void main(String[] args) { verifyJUnit4Present(); PrintStream serr = System.err; try { SlaveMain.main(args); } catch (Throwable e) { serr.println(e.toString()); e.printStackTrace(serr); System.out.close(); System.err.close(); JvmExit.halt(SlaveMain.ERR_EXCEPTION); } } /** * Verify JUnit presence and version. */ private static void verifyJUnit4Present() { try { Class clazz = Class.forName("org.junit.runner.Description"); if (!Serializable.class.isAssignableFrom(clazz)) { JvmExit.halt(SlaveMain.ERR_OLD_JUNIT); } } catch (ClassNotFoundException e) { JvmExit.halt(SlaveMain.ERR_NO_JUNIT); } } } StdInLineIterator.java000066400000000000000000000017041235451432000371450ustar00rootroot00000000000000randomizedtesting-release-2.1.6/junit4-ant/src/main/java/com/carrotsearch/ant/tasks/junit4/slavepackage com.carrotsearch.ant.tasks.junit4.slave; import java.io.*; import java.nio.charset.Charset; import com.carrotsearch.ant.tasks.junit4.events.IdleEvent; import com.carrotsearch.ant.tasks.junit4.events.Serializer; import com.google.common.collect.AbstractIterator; /** * Iterates over lines from standard input. */ class StdInLineIterator extends AbstractIterator { private BufferedReader reader; private Serializer serializer; public StdInLineIterator(Serializer serializer) { this.serializer = serializer; this.reader = new BufferedReader( new InputStreamReader( System.in, Charset.defaultCharset())); } @Override protected String computeNext() { try { serializer.serialize(new IdleEvent()); serializer.flush(); String line = reader.readLine(); return line != null ? line : endOfData(); } catch (IOException e) { throw new RuntimeException(e); } } } StreamFlusherDecorator.java000066400000000000000000000007231235451432000402310ustar00rootroot00000000000000randomizedtesting-release-2.1.6/junit4-ant/src/main/java/com/carrotsearch/ant/tasks/junit4/slavepackage com.carrotsearch.ant.tasks.junit4.slave; import org.junit.runner.notification.RunListener; /** * Flushes {@link System#out} and {@link System#err} before * passing the event to the delegate. */ public final class StreamFlusherDecorator extends BeforeAfterRunListenerDecorator { public StreamFlusherDecorator(RunListener delegate) { super(delegate); } @Override protected void before() { System.out.flush(); System.err.flush(); } } randomizedtesting-release-2.1.6/junit4-ant/src/main/java/com/carrotsearch/ant/tasks/junit4/tools/000077500000000000000000000000001235451432000330425ustar00rootroot00000000000000DumpStreamsFromEventStream.java000066400000000000000000000045271235451432000411040ustar00rootroot00000000000000randomizedtesting-release-2.1.6/junit4-ant/src/main/java/com/carrotsearch/ant/tasks/junit4/toolspackage com.carrotsearch.ant.tasks.junit4.tools; import java.io.BufferedInputStream; import java.io.BufferedOutputStream; import java.io.File; import java.io.FileInputStream; import java.io.FileOutputStream; import java.io.InputStream; import java.io.InputStreamReader; import java.io.OutputStream; import com.carrotsearch.ant.tasks.junit4.events.EventType; import com.carrotsearch.ant.tasks.junit4.events.IStreamEvent; import com.carrotsearch.ant.tasks.junit4.events.Serializer; import com.google.common.base.Charsets; import com.google.common.io.Closer; import com.google.gson.Gson; import com.google.gson.stream.JsonReader; import com.google.gson.stream.JsonToken; public class DumpStreamsFromEventStream { public static void main(String[] args) throws Exception { File inputFile; if (args.length != 1) { System.err.println("Usage: [input.events]"); System.exit(1); return; } else { inputFile = new File(args[0]); } Gson gson = Serializer.createGSon(DumpStreamsFromEventStream.class.getClassLoader()); Closer closer = Closer.create(); try { OutputStream sysout = new BufferedOutputStream(new FileOutputStream(new File(inputFile.getAbsolutePath() + ".sysout"))); closer.register(sysout); OutputStream syserr = new BufferedOutputStream(new FileOutputStream(new File(inputFile.getAbsolutePath() + ".syserr"))); closer.register(syserr); InputStream is = new BufferedInputStream(new FileInputStream(inputFile)); closer.register(is); JsonReader input = new JsonReader(new InputStreamReader(is, Charsets.UTF_8)); input.setLenient(true); JsonToken peek; while (true) { peek = input.peek(); if (peek == JsonToken.END_DOCUMENT) { return; } input.beginArray(); EventType type = EventType.valueOf(input.nextString()); switch (type) { case APPEND_STDERR: ((IStreamEvent) gson.fromJson(input, type.eventClass)).copyTo(syserr); break; case APPEND_STDOUT: ((IStreamEvent) gson.fromJson(input, type.eventClass)).copyTo(sysout); break; default: input.skipValue(); } input.endArray(); } } catch (Throwable t) { throw closer.rethrow(t); } finally { closer.close(); } } } randomizedtesting-release-2.1.6/junit4-ant/src/main/resources/000077500000000000000000000000001235451432000244115ustar00rootroot00000000000000randomizedtesting-release-2.1.6/junit4-ant/src/main/resources/com/000077500000000000000000000000001235451432000251675ustar00rootroot00000000000000randomizedtesting-release-2.1.6/junit4-ant/src/main/resources/com/carrotsearch/000077500000000000000000000000001235451432000276475ustar00rootroot00000000000000randomizedtesting-release-2.1.6/junit4-ant/src/main/resources/com/carrotsearch/ant/000077500000000000000000000000001235451432000304315ustar00rootroot00000000000000randomizedtesting-release-2.1.6/junit4-ant/src/main/resources/com/carrotsearch/ant/tasks/000077500000000000000000000000001235451432000315565ustar00rootroot00000000000000randomizedtesting-release-2.1.6/junit4-ant/src/main/resources/com/carrotsearch/ant/tasks/junit4/000077500000000000000000000000001235451432000327735ustar00rootroot00000000000000000077500000000000000000000000001235451432000347125ustar00rootroot00000000000000randomizedtesting-release-2.1.6/junit4-ant/src/main/resources/com/carrotsearch/ant/tasks/junit4/templates000077500000000000000000000000001235451432000356635ustar00rootroot00000000000000randomizedtesting-release-2.1.6/junit4-ant/src/main/resources/com/carrotsearch/ant/tasks/junit4/templates/json000077500000000000000000000000001235451432000364535ustar00rootroot00000000000000randomizedtesting-release-2.1.6/junit4-ant/src/main/resources/com/carrotsearch/ant/tasks/junit4/templates/json/cssstyle.css000066400000000000000000000461761235451432000403430ustar00rootroot00000000000000randomizedtesting-release-2.1.6/junit4-ant/src/main/resources/com/carrotsearch/ant/tasks/junit4/templates/json/css/* * HTML5 Boilerplate * * What follows is the result of much research on cross-browser styling. * Credit left inline and big thanks to Nicolas Gallagher, Jonathan Neal, * Kroc Camen, and the H5BP dev community and team. */ /* ============================================================================= HTML5 element display ========================================================================== */ article, aside, details, figcaption, figure, footer, header, hgroup, nav, section { display: block; } audio[controls], canvas, video { display: inline-block; *display: inline; *zoom: 1; } /* ============================================================================= Base ========================================================================== */ /* * 1. Correct text resizing oddly in IE6/7 when body font-size is set using em units * http://clagnut.com/blog/348/#c790 * 2. Force vertical scrollbar in non-IE * 3. Remove Android and iOS tap highlight color to prevent entire container being highlighted * www.yuiblog.com/blog/2010/10/01/quick-tip-customizing-the-mobile-safari-tap-highlight-color/ * 4. Prevent iOS text size adjust on device orientation change, without disabling user zoom * www.456bereastreet.com/archive/201012/controlling_text_size_in_safari_for_ios_without_disabling_user_zoom/ */ html { font-size: 100%; overflow-y: scroll; -webkit-overflow-scrolling: touch; -webkit-tap-highlight-color: rgba(0,0,0,0); -webkit-text-size-adjust: 100%; -ms-text-size-adjust: 100%; } body { margin: 0; font-size: 13px; line-height: 1.231; } body, button, input, select, textarea { font-family: sans-serif; color: #222; } /* * These selection declarations have to be separate * No text-shadow: twitter.com/miketaylr/status/12228805301 * Also: hot pink! */ ::-moz-selection { background: #fe57a1; color: #fff; text-shadow: none; } ::selection { background: #fe57a1; color: #fff; text-shadow: none; } /* ============================================================================= Links ========================================================================== */ a { color: #00e; } a:visited { color: #551a8b; } a:focus { outline: thin dotted; } /* Improve readability when focused and hovered in all browsers: people.opera.com/patrickl/experiments/keyboard/test */ a:hover, a:active { outline: 0; } /* ============================================================================= Typography ========================================================================== */ abbr[title] { border-bottom: 1px dotted; } b, strong { font-weight: bold; } blockquote { margin: 1em 40px; } dfn { font-style: italic; } hr { display: block; height: 1px; border: 0; border-top: 1px solid #ccc; margin: 1em 0; padding: 0; } ins { background: #ff9; color: #000; text-decoration: none; } mark { background: #ff0; color: #000; font-style: italic; font-weight: bold; } /* Redeclare monospace font family: en.wikipedia.org/wiki/User:Davidgothberg/Test59 */ pre, code, kbd, samp { font-family: monospace, monospace; _font-family: 'courier new', monospace; font-size: 1em; } /* Improve readability of pre-formatted text in all browsers */ pre { white-space: pre; white-space: pre-wrap; word-wrap: break-word; } q { quotes: none; } q:before, q:after { content: ""; content: none; } small { font-size: 85%; } /* Position subscript and superscript content without affecting line-height: gist.github.com/413930 */ sub, sup { font-size: 75%; line-height: 0; position: relative; vertical-align: baseline; } sup { top: -0.5em; } sub { bottom: -0.25em; } /* ============================================================================= Lists ========================================================================== */ ul, ol { margin: 1em 0; padding: 0 0 0 40px; } dd { margin: 0 0 0 40px; } nav ul, nav ol { list-style: none; margin: 0; padding: 0; } /* ============================================================================= Embedded content ========================================================================== */ /* * Improve image quality when scaled in IE7 * code.flickr.com/blog/2008/11/12/on-ui-quality-the-little-things-client-side-image-resizing/ */ img { border: 0; -ms-interpolation-mode: bicubic; } /* * Correct overflow displayed oddly in IE9 */ svg:not(:root) { overflow: hidden; } /* ============================================================================= Figures ========================================================================== */ figure { margin: 0; } /* ============================================================================= Forms ========================================================================== */ form { margin: 0; } fieldset { border: 0; margin: 0; padding: 0; } /* * 1. Correct color not inheriting in IE6/7/8/9 * 2. Correct alignment displayed oddly in IE6/7 */ legend { border: 0; *margin-left: -7px; padding: 0; } /* Indicate that 'label' will shift focus to the associated form element */ label { cursor: pointer; } /* * 1. Correct font-size not inheriting in all browsers * 2. Remove margins in FF3/4 S5 Chrome * 3. Define consistent vertical alignment display in all browsers */ button, input, select, textarea { font-size: 100%; margin: 0; vertical-align: baseline; *vertical-align: middle; } /* * 1. Define line-height as normal to match FF3/4 (set using !important in the UA stylesheet) * 2. Correct inner spacing displayed oddly in IE6/7 */ button, input { line-height: normal; *overflow: visible; } /* * 1. Display hand cursor for clickable form elements * 2. Allow styling of clickable form elements in iOS */ button, input[type="button"], input[type="reset"], input[type="submit"] { cursor: pointer; -webkit-appearance: button; } /* * Consistent box sizing and appearance */ input[type="checkbox"], input[type="radio"] { box-sizing: border-box; } input[type="search"] { -moz-box-sizing: content-box; -webkit-box-sizing: content-box; box-sizing: content-box; } /* * Remove inner padding and border in FF3/4 * www.sitepen.com/blog/2008/05/14/the-devils-in-the-details-fixing-dojos-toolbar-buttons/ */ button::-moz-focus-inner, input::-moz-focus-inner { border: 0; padding: 0; } /* Remove default vertical scrollbar in IE6/7/8/9 */ textarea { overflow: auto; vertical-align: top; } /* Colors for form validity */ input:valid, textarea:valid { } input:invalid, textarea:invalid { background-color: #f0dddd; } /* ============================================================================= Tables ========================================================================== */ table { border-collapse: collapse; border-spacing: 0; } /* ============================================================================= Primary styles ========================================================================== */ body { line-height: 1.3; background-color: #f4f4f4; } header { padding: 10px 0; margin-top: 10px; margin-right: 340px; border-top-right-radius: 5px; border-bottom-right-radius: 5px; height: 40px; } header > h1 { font-size: 18px; font-weight: normal; text-shadow: 1px 1px 1px rgba(0, 0, 0, 0.5); line-height: 1.0; margin: 0 10px 0 0; color: white; padding-left: 20px; border-left: none !important; border-top-right-radius: 2px; border-bottom-right-radius: 2px; height: 38px; line-height: 38px; } header > h1 > span { vertical-align: -15%; width: 28px; height: 20px; display: inline-block; background-repeat: no-repeat; } header > h1 > strong { padding-left: 0.2em; } #container, #summary { background-color: #fff; border-color: #e4e4e4; border-style: solid; border-width: 1px; box-shadow: 0 0 7px rgba(0, 0, 0, 0.07); } #container { margin-top: 10px; padding: 20px; border-left-width: 0; border-left-width: 0; border-right-width: 0; border-bottom-width: 0; } #summary { border-right: none; border-bottom: none; border-top-left-radius: 5px; position: absolute; right: 0; top: 10px; width: 320px; height: 59px; padding: 8px 0 5px 9px; } #mask { position: absolute; right: 0; top: 81px; width: 330px; height: 5px; background-color: white; } #summary > p { margin: 0 0 2px 0; } #summary.empty { color: #888; line-height: 52px; } header.FAILURE { background-color: #ce4747; } header.FAILURE > h1 { border: 1px solid #b51414; background-color: #be1414; } header.FAILURE > h1 > span { background-image: url(../img/failure.png); } header.ERROR { background-color: #f4a337; } header.ERROR > h1 { border: 1px solid #d37700; background-color: #e07f00; } header.ERROR > h1 > span { background-image: url(../img/error.png); width: 20px; } header.OK { background-color: #3ac939; } header.OK > h1 { border: 1px solid #07a000; background-color: #08ad00; } header.OK > h1 > span { background-image: url(../img/pass.png); background-position: 0 2px; width: 25px; } a, a:visited { color: #444; text-decoration: none; border-bottom: 1px dotted #444; } .tag { border-radius: 2px; color: #fff; padding: 0 2px; font-size: 11px; } .OK { background-color: #09c500; } .IGNORED_ASSUMPTION { background-color: #69d600; } .IGNORED { background-color: #bfe200; } .ERROR { background-color: #ef8700; } .FAILURE { background-color: #ef0000; } .statusbar { list-style: none; margin: 5px 0 0; padding: 0; position: relative; } #summary > .statusbar { width: 30%; min-width: 300px; margin-top: 7px; } td > .statusbar { width: 100%; margin: 0; } .statusbar > li { position: absolute; height: 10px; min-width: 1px; } .statusbar > li:first-child { border-top-left-radius: 2px; border-bottom-left-radius: 2px; } .statusbar > li:last-child { border-top-right-radius: 2px; border-bottom-right-radius: 2px; } /* Results table */ #results > table { width: 100%; table-layout: fixed; } #results > table > thead > tr > th { font-weight: normal; } #results > table > thead > tr > th:first-child { text-align: left; } #results > table > thead > tr > th, #results > table > tbody > tr > td { padding: 7px; border: 1px solid #f0f0f0; } #results > table > thead > tr > th { border-top: none; } #results > table.no-results > thead > tr > th { border: none; } th { white-space: nowrap; } th.sortable { cursor: pointer; } th.signature, td.signature { white-space: nowrap; overflow: hidden; text-overflow: ellipsis; } tr.drilldown { cursor: pointer; } th.count { width: 4em; } th.result { width: 7em; } #results.methods > table th.result { width: 5em; } #results.methods > table > tbody > tr > td.result { padding-top: 6px; } #results > table > tbody > tr > td.result { padding-top: 0; } th.result > span { font-size: 13px; color: #000; } th.slave { width: 3.8em; } th.timestamp { width: 7em; } th.time { width: 6.5em; } th.pass, th.ignored, th.error, th.failed { width: 3.8em; } td.numeric { text-align: right; } td > em { font-style: normal; background-color: #ffffd8; } .signature > .stacktrace { padding: 5px 0; font-family: "Consolas", "Bitstream Vera Sans Mono", "Courier New", Courier, monospace; font-size: 11px; line-height: 1.4; color: #888; margin: 10px 0; cursor: pointer; } .signature > .stacktrace:first-of-type { margin-top: 0; } .signature:hover > .stacktrace { color: #000; } .signature > .stacktrace:first-child { margin-top: 0; } .signature > .stacktrace:last-child { margin-bottom: 0; } .signature > .stacktrace > div, .signature > .stacktrace > span { white-space: nowrap; margin-left: 30px; } .signature > .stacktrace > div:first-child { margin-left: 0; white-space: normal; } .signature > .stacktrace > div.filtered { display: none; color: #888; } .signature.fullStacktrace > .stacktrace > div.filtered { display: block; } .signature > .stacktrace > span { cursor: pointer; display: block; position: absolute; margin-left: 0px; margin-top: -8px; width: 18px; height: 7px; background: url(../img/omited.png) no-repeat 8px 5px; padding: 3px 5px; } .signature.fullStacktrace > .stacktrace > span { display: none; } .stdout, .stderr { background-repeat: no-repeat; width: 13px; height: 13px; float: right; margin-top: 1px; opacity: 0.6; cursor: pointer; } .stdout:hover, .stderr:hover { opacity: 1.0; } .stdout { background-image: url(../img/stdout.png); } .stderr { background-image: url(../img/stderr.png); } #results > table > thead.empty > tr > th { text-align: center; padding: 20px 0; } #results { margin-top: 10px; } #results > table > tbody > tr:nth-child(odd) > td { background-color: #f8f8f8; } #results > table > tbody > tr:nth-child(even) > td { background-color: #fff; } #results > table > tbody > tr:hover > td { background-color: #fffeda; } #results > table > thead > tr > th.desc, #results > table > thead > tr > th.asc { padding-left: 2px; padding-right: 2px; } #results > table > thead > tr > th.asc.signature, #results > table > thead > tr > th.desc.signature { padding: 7px; } #results > table > thead > tr > th.desc > span, #results > table > thead > tr > th.asc > span { background-position: right center; background-repeat: no-repeat; padding-right: 13px; padding-top: 1px; font-weight: bold; } #results > table > thead > tr > th.asc > span { background-image: url(../img/arrow-up.png); } #results > table > thead > tr > th.desc > span { background-image: url(../img/arrow-down.png); } #tools { text-align: right; border-bottom: 2px solid #bbb; padding-bottom: 4px; } #tools > span > a { border: 0; padding-bottom: 4px; background: no-repeat center bottom; margin-left: 5px; } #tools > span > a.active { background-image: url(../img/indicator.png); } #tools > input[type='search'] { float: left; position: relative; top: -8px; width: 45%; border: 1px solid #e0e0e0; padding: 3px; border-radius: 2px; -webkit-appearance: none; } #tools > span { padding-left: 2em; } a[href ^= '#withoutoutput'] { display: none; } #results.console a[href ^= '#withoutoutput'] { display: inline; } #console { position: relative; border: 1px solid #f0f0f0; border-top: none; padding: 15px 0 0 0; margin: 0; overflow: hidden; } #console canvas { pointer-events: none; position: absolute; left: 280px; right: 0; top: 16px; bottom: 0; padding: 0; margin: 0; } .suitebox { clear: both; margin-bottom: 2em; position: relative; } .suitebox > .name { margin-left: 300px; color: #777; } .outbox { background-color: #F8F8F8; margin-top: 0px; margin-bottom: 0px; margin-left: 300px; /* Maybe we should now wrap? */ white-space: pre; white-space: pre-wrap; word-wrap: break-word; font-family: "Consolas", "Bitstream Vera Sans Mono", "Courier New", Courier, monospace; font-size: 13px; padding: 2px 4px; } .outbox.empty { padding: 0 2px; } .side { float: left; width: 0; clear: both; } .side > div { position: relative; right: 300px; width: 280px; margin-bottom: 2px; text-align: right; } .side > div > span { padding: 1px 4px; font-family: sans-serif; font-size: 12px; } .outbox .test .start, .outbox .failure { position: absolute; margin-top: -2px; margin-left: -3px; /** A CSS arrow */ width: 0; height: 0; border-top: 4px solid transparent; border-bottom: 4px solid transparent; border-left: 4px solid transparent; -webkit-transform: rotate(225deg) scale(0.90); -moz-transform: rotate(225deg) scale(0.90); -ms-transform: rotate(225deg) scale(0.90); -o-transform: rotate(225deg) scale(0.90); transform: rotate(225deg) scale(0.90); } .outbox .test .start { border-left-color: #777; } .outbox .failure { border-left-color: #ef0000; } .outbox .out { color: black; } .outbox .err { color: red; } #results > table > tbody > tr.highlight > td, .test.highlight .out, .test.highlight .err, .highlight.out, .highlight.err { background-color: rgb(255, 247, 199); } .suitebox.highlight .label { opacity: 0.35; -webkit-transition: all 0.3s ease-out; } .suitebox .label, .suitebox.highlight .label.highlight { opacity: 1.0; -webkit-transition: all 0.3s ease-out; } .label.test { cursor: pointer; } .nooutput { text-align: center; margin: 7px 0 20px; } /* ============================================================================= Non-semantic helper classes Please define your styles before this section. ========================================================================== */ /* For image replacement */ .ir { display: block; text-indent: -999em; overflow: hidden; background-repeat: no-repeat; text-align: left; direction: ltr; } .ir br { display: none; } /* Hide for both screenreaders and browsers: css-discuss.incutio.com/wiki/Screenreader_Visibility */ .hidden { display: none; visibility: hidden; } /* Hide only visually, but have it available for screenreaders: by Jon Neal. www.webaim.org/techniques/css/invisiblecontent/ & j.mp/visuallyhidden */ .visuallyhidden { border: 0; clip: rect(0 0 0 0); height: 1px; margin: -1px; overflow: hidden; padding: 0; position: absolute; width: 1px; } /* Extends the .visuallyhidden class to allow the element to be focusable when navigated to via the keyboard: drupal.org/node/897638 */ .visuallyhidden.focusable:active, .visuallyhidden.focusable:focus { clip: auto; height: auto; margin: 0; overflow: visible; position: static; width: auto; } /* Hide visually and from screenreaders, but maintain layout */ .invisible { visibility: hidden; } /* Contain floats: nicolasgallagher.com/micro-clearfix-hack/ */ .clearfix:before, .clearfix:after { content: ""; display: table; } .clearfix:after { clear: both; } .clearfix { zoom: 1; } /* ============================================================================= PLACEHOLDER Media Queries for Responsive Design. These override the primary ('mobile first') styles Modify as content requires. ========================================================================== */ @media only screen and (min-width: 480px) { /* Style adjustments for viewports 480px and over go here */ } @media only screen and (min-width: 768px) { /* Style adjustments for viewports 768px and over go here */ } /* ============================================================================= Print styles. Inlined to avoid required HTTP connection: www.phpied.com/delay-loading-your-print-css/ ========================================================================== */ @media print { * { background: transparent !important; color: black !important; text-shadow: none !important; filter:none !important; -ms-filter: none !important; } /* Black prints faster: sanbeiji.com/archives/953 */ a, a:visited { color: #444 !important; text-decoration: underline; } a[href]:after { content: " (" attr(href) ")"; } abbr[title]:after { content: " (" attr(title) ")"; } .ir a:after, a[href^="javascript:"]:after, a[href^="#"]:after { content: ""; } /* Don't show links for images, or javascript/internal links */ pre, blockquote { border: 1px solid #999; page-break-inside: avoid; } thead { display: table-header-group; } /* css-discuss.incutio.com/wiki/Printing_Tables */ tr, img { page-break-inside: avoid; } img { max-width: 100% !important; } @page { margin: 0.5cm; } p, h2, h3 { orphans: 3; widows: 3; } h2, h3{ page-break-after: avoid; } } ideas.txt000066400000000000000000000044331235451432000375150ustar00rootroot00000000000000randomizedtesting-release-2.1.6/junit4-ant/src/main/resources/com/carrotsearch/ant/tasks/junit4/templates/jsonBUGS: * search highlighting does not work in method view TODO, must have: * Console output generated by package, class and method * Unified (linear) console log view across all tests (alternative to package/class/method view) * Showing information about slaves * Showing RR-specific annotations * Indication next to package/class/method that there was console output * Display of global overrides * Detailed test method view * class name * method name * annotations: * seeds * repetitions * timeout * expected exceptions * slave * staus: ok, ignored by assumption, ignored by annotation, failed, error * execution time * stack trace * console output * ignored by assumption vs by annotation in descriptions * global start date in header (because individual tests report just time) * multiple column sorting tip * fix white gaps in status bar * keyboard navigation + hints * fix changing column width when adding sorting * drop the array/push/joing paradigm for string building, string concatenation is now faster Nice to have: * paging in method view on slow machines? * Automatic/configurable abbreviation of package names * Deemphasizing common prefix (package, class name) in class and method view. * Minification of assets * Clean-up of data JSON (smaller size) * Table filters: by status * bookmarkable links * Links for opening in an IDE * Copying stack trace to clipboard? To decide: * Generation of markup in JS makes things easy, but is terrible for indexing in search engines. Maybe there should be some pre-rendered version as well? * Showing aggregations by the slave they ran on (like by package/method)? * Mobile version? Testing: * Empty report * All failures * All errors * All ignored * All passed * One vs many (string formatting) * Performance * Classes in the default package DONE: * Showing test in the execution order (only in method view), per slave order * Showing failing tests first (if any test failed/errored) * General indication of ok / failure in document title * A "bulb" indication of general ok / failure (green/red, like in Bamboo) * Table filters: free text * navigation: package -> class -> method and back * Hiding irrelevant parts of the stack trace? (filtering of certain packages) * navigation using HTML5 history API (bookmarkable urls) 000077500000000000000000000000001235451432000364375ustar00rootroot00000000000000randomizedtesting-release-2.1.6/junit4-ant/src/main/resources/com/carrotsearch/ant/tasks/junit4/templates/json/imgarrow-down.png000066400000000000000000000002501235451432000412410ustar00rootroot00000000000000randomizedtesting-release-2.1.6/junit4-ant/src/main/resources/com/carrotsearch/ant/tasks/junit4/templates/json/img‰PNG  IHDR FntEXtSoftwareAdobe ImageReadyqÉe<JIDATxÚÄ1 ¡ñ¯¼‰×bpj›7–’R4"„1³%¸»²yä£qœŽ¯åP…Δh¾§31™†[,ÏP…δµæA]œ ‚:#uèVBIEND®B`‚arrow-up.png000066400000000000000000000002421235451432000407170ustar00rootroot00000000000000randomizedtesting-release-2.1.6/junit4-ant/src/main/resources/com/carrotsearch/ant/tasks/junit4/templates/json/img‰PNG  IHDR FntEXtSoftwareAdobe ImageReadyqÉe<DIDATxÚbüÿÿ?2HOO Ìœ9“Yœ ›"t6ŠBt t1&\ŠÐ3!+Bv2¤† ›61F²|  B€¼5&߃FT\IEND®B`‚error.png000066400000000000000000000010601235451432000402730ustar00rootroot00000000000000randomizedtesting-release-2.1.6/junit4-ant/src/main/resources/com/carrotsearch/ant/tasks/junit4/templates/json/img‰PNG  IHDR ¹ðÜtEXtSoftwareAdobe ImageReadyqÉe<ÒIDATxÚ„S=HBQ~–QH¾Á¡"("ƒ ‚–Z) Zj,ÚZãAÑ$ACHƒC›D`½ ‚‚ÄÅÐÐô¡™úôõ]¸Â+S/|¼sÎ=çÜïžû=†é°4M3W*•M·Ûm‚ËwÊgTU=Ëf³‡0EÀȵK®V«;Çy‚Áà=Ü>€k×yt4EQd¸ó€ èú·œgÑù˜Ø±XL¦¿È¡M¥Ri˜çùs–eEPhöw"½ r£Ñ•L&_DQ\ÁÖ¡Ãè/}¾V«Iè¾ÐˆÎS:þ„©k‘«›È {úãñøC¹\~Å)E“Éd€ý֘ȆÖaÕëu5 í’d7üj§\þ½PËår—©TÊP( ‹Åj·Û'õÔÂáð•Ç㹆ùA|#0L3ÑhôTßY–åø¯ao03TP=@¿ËåñwäD"ñl³ÙÖ±7Gµ$üz‡b±è@žJ’!¸w§Ó¹0³04Icó“d|ŸÏçGh‰j¨»•:oI$IGp—QJ—ýOpÌú;‰H4y¢­¤Ac?“É\P)“±´L&:Êçó[^¯×wlõ;þ0~Ê7W÷Ü.¨IEND®B`‚failure.png000066400000000000000000000014711235451432000405770ustar00rootroot00000000000000randomizedtesting-release-2.1.6/junit4-ant/src/main/resources/com/carrotsearch/ant/tasks/junit4/templates/json/img‰PNG  IHDRÄ´l;tEXtSoftwareAdobe ImageReadyqÉe<ÛIDATxÚ¤•MlQ…gJD­ÄŸR;UÓ¢.ꪘHlmM41¬HL›º–€º3®”ÄuW&$&lʦ)héÂBw¡RˆZ­Ä’–ßÒñÜfÇ)0i}ÉIȼó>Þܹç=F†T,¡ñt:=È0Œb¥¹&ê®V«7²ÙìexÛÉÏÈ™*•Ê¥ííí~ år9 oaê`3øææ&·µµµ@~¬+F£Ñ‡ðÚê`@M˜ü"ÈvÎ L"³Úè¢Ü_«Õª‘Hä‰N§;Z‡ŒB¡°6??? Ëa¼Ðwüx^r»Ý·Å³m,˘C«Õê­V«{nnŽÊ¢E-û±³€F£oäÇó®R©D,ÝÎ7ÊårÏ…¯þ# =À¢7­|+++Ÿ‡‡‡ïJ¿ƒ1 ºT*5+üÇ@'ÅÌfó}¯@=RÛGFFú‰Ä‹ý@3™L|tt” × ÓPW½Ý®×ë{———ý{Òë›L&§ÊÖÁ|``àd<ŸÅ®¨A“Éä'‹Årë®î‚ÊÁÜëõ^DogÕÀÓÓÓÏà¿©¿¾2y’666zÓ·Ôójà|>¿†¾µqìŸÄ)Áb¢B{©1µ¢ßº ,fq?]„ò>Ÿobs½€[-F‰~«À‰ñÿ ôµJKEm6Û£p8üJ¥,ß].טt*2*‰¢>uÀ8Æqœqiiée+ÿÌÌÌcx¹óÿ´Ð,¦b¢¤>¥×Ô#D¾FþõõõŸSSS´‰³P'ãñxÎó<ÿAS1ûÊDµFN™P´ït:ŸŠ}͉7 Óép8.¬®®¾§35‹}Ä)uW™(yˆ†††úpkxÉãô«ÝnwáùMèœTc)‚´øt ê†òÐ7ˆ§K†šGÑþ´#º-ú¡ã¢‡ükPüò °C¬c‡h$C•i>®…@5Ñ_–6ñG€™Nyî fÓIEND®B`‚indicator.png000066400000000000000000000002131235451432000411150ustar00rootroot00000000000000randomizedtesting-release-2.1.6/junit4-ant/src/main/resources/com/carrotsearch/ant/tasks/junit4/templates/json/img‰PNG  IHDRBÆ%}tEXtSoftwareAdobe ImageReadyqÉe<-IDATxÚbøÿÿ? ïÞ½û?2Ÿ‰ öìÙó™&td>#È( À£% Mqr‡IEND®B`‚omited.png000066400000000000000000000002751235451432000404320ustar00rootroot00000000000000randomizedtesting-release-2.1.6/junit4-ant/src/main/resources/com/carrotsearch/ant/tasks/junit4/templates/json/img‰PNG  IHDR2 íMtEXtSoftwareAdobe ImageReadyqÉe<PLTEþþþÌÌÌÝÝݳ³³YYYÿÿÿ0èõ+tRNSÿÿÿÿÿ³¿¤¿/IDATxÚb`eD¬¬¬ Œ (€"ÄÄÌÇ@13 3Åp¨B7 ÓF€. µT/€IEND®B`‚pass.png000066400000000000000000000010231235451432000401070ustar00rootroot00000000000000randomizedtesting-release-2.1.6/junit4-ant/src/main/resources/com/carrotsearch/ant/tasks/junit4/templates/json/img‰PNG  IHDRÝDŒ¾tEXtSoftwareAdobe ImageReadyqÉe<µIDATxÚ¬”ÍJQÇ›F¤ÁEi©X¾€‹2©…­Ây€"*hÕ¦Gè5*²­«ÁJÍ‹\–ƒ«6&Eˆ É âçô¿âÈ8ŸtàÏÌœ{ÎoΜ3÷R’$Mý«M l4‡'Šâ™Ó霅K719VÀq•êõúßï?bYÖ‚¥é±åry °„¤°Z­&ær¹k,ÇjÁdá!ݨ°R©dÓëõw4M»Ôkétú9 =à–é©°R©Ø³Ùì\»ªÊšÍæ‹Ve©TêÉ`0 l²whîI«ÕзX,¶× Dá%Ë€½jÁ’Éd¼Û€lí$0e ß^¯—åy~0^ Æq\œa˜ýÌÚóÛ ²u …jµúÙ¯2ôréë¥ “ÅbñRÑ¢Ñè=†³« “n·Ûˆa\ ƒ…Ãá¤ì@kùL±SÈ‚» fZ…æ!zØ^&Ð â\ ‹D"· ˜©/Lc/“@*=•aÁ`002¬Ïá@û|>G>Ÿg2™„Çã9†Ï5ð3F EQjûó¡ÅÎóT §Ö0à¯Þ}íx»¢»YIEND®B`‚stderr.png000066400000000000000000000007221235451432000404510ustar00rootroot00000000000000randomizedtesting-release-2.1.6/junit4-ant/src/main/resources/com/carrotsearch/ant/tasks/junit4/templates/json/img‰PNG  IHDR rëä|tEXtSoftwareAdobe ImageReadyqÉe<tIDATxÚŒQ=/Q=ïc– ±É B¡Ñ¡°‰Ú­FÂoµDDC¯Ò(”¡Dh%"Ù,ÙÝÙ™Y3ϹoÆ†Š—ÌÜûÞ=çÞwÎS7Õ7x~‰ÿ®§êÔzÝáìô¿Ió'°ŸLŒ1XYßù“°·±Á“¤ •ñ‡ÙXEþpZAeŽ(ç”4·HY'‰¿ž’']/Ì¡·ñÑj Á/Œ#,žÞB Ë(˜ @ ›°›±'Mìä÷ F†øÇø>œŸ”2&']­.ù¥ Â0D³ÕD˜Dˆ“ËÇg°V&©bR_ors›’\ÞX£d/yÒ-•àåt¤Nùî,ižèÉ”¿²\/¡#6¢@k-Žö·èš¦k«š ³”A‹ÞUC—cqönhĽ×ê…ÖÜânN½ ©ë ÏúÊ„8÷ëï‡GÝK½^hÓ诔1þø ~b¢~$ûÛ3AĬSXÎ <Ô¨à'®éÄߣ:JÔiŒ`>PAØlë:ú"—A4P·¡œ[W¡ž\#Fr0*®ïû NS×qÆÞIÊ(Õ\5ùA,Ê¥…&¸Ï;¥.=±³7—×rϾèÜŠ§PÞEã‚;§òú2Ú/PÔ£`\ÙXsä_¸W½ã^ï9'•Jè4©¨QÈ Ÿ|>ô—RE÷reS| 0Ÿf—¨¢TIEND®B`‚index.html000066400000000000000000000020501235451432000376550ustar00rootroot00000000000000randomizedtesting-release-2.1.6/junit4-ant/src/main/resources/com/carrotsearch/ant/tasks/junit4/templates/json

000077500000000000000000000000001235451432000362775ustar00rootroot00000000000000randomizedtesting-release-2.1.6/junit4-ant/src/main/resources/com/carrotsearch/ant/tasks/junit4/templates/json/jstests-output.jsonp000066400000000000000000001543431235451432000414500ustar00rootroot00000000000000randomizedtesting-release-2.1.6/junit4-ant/src/main/resources/com/carrotsearch/ant/tasks/junit4/templates/jsontestData({ "junit4": { "tests.seed": "B19FBD1BB1231191", "project.name": "Nice project" }, "suites": [ { "slave": 0, "startTimestamp": 1331889914622, "startTimestampDate": "2012-03-16T10:25:14.622", "executionTime": 109, "description": { "id": "id#com.carrotsearch.ant.tasks.junit4.tests.TestBeforeClassError[0]", "displayName": "com.carrotsearch.ant.tasks.junit4.tests.TestBeforeClassError", "className": "com.carrotsearch.ant.tasks.junit4.tests.TestBeforeClassError", "annotations": [], "children": [ { "id": "id#method(com.carrotsearch.ant.tasks.junit4.tests.TestBeforeClassError)[1]", "displayName": "method(com.carrotsearch.ant.tasks.junit4.tests.TestBeforeClassError)", "methodName": "method", "className": "com.carrotsearch.ant.tasks.junit4.tests.TestBeforeClassError", "annotations": [ { "org.junit.Test": { "timeout": 0, "expected": "org.junit.Test$None" } } ], "children": [] } ] }, "tests": [], "suiteFailures": [ { "throwableClass": "java.lang.RuntimeException", "throwableString": "java.lang.RuntimeException", "stackTrace": "java.lang.RuntimeException\n\tat com.carrotsearch.ant.tasks.junit4.tests.TestBeforeClassError.beforeClass(TestBeforeClassError.java:9)\n\tat sun.reflect.NativeMethodAccessorImpl.invoke0(Native Method)\n\tat sun.reflect.NativeMethodAccessorImpl.invoke(NativeMethodAccessorImpl.java:39)\n\tat sun.reflect.DelegatingMethodAccessorImpl.invoke(DelegatingMethodAccessorImpl.java:25)\n\tat java.lang.reflect.Method.invoke(Method.java:597)\n\tat org.junit.runners.model.FrameworkMethod$1.runReflectiveCall(FrameworkMethod.java:45)\n\tat org.junit.internal.runners.model.ReflectiveCallable.run(ReflectiveCallable.java:15)\n\tat org.junit.runners.model.FrameworkMethod.invokeExplosively(FrameworkMethod.java:42)\n\tat org.junit.internal.runners.statements.RunBefores.evaluate(RunBefores.java:27)\n\tat org.junit.runners.ParentRunner.run(ParentRunner.java:300)\n\tat org.junit.runner.JUnitCore.run(JUnitCore.java:157)\n\tat com.carrotsearch.ant.tasks.junit4.slave.SlaveMain.execute(SlaveMain.java:129)\n\tat com.carrotsearch.ant.tasks.junit4.slave.SlaveMain.main(SlaveMain.java:202)\n\tat com.carrotsearch.ant.tasks.junit4.slave.SlaveMainSafe.main(SlaveMainSafe.java:12)\n", "kind": "error" } ], "executionEvents": [ { "event": "SUITE_FAILURE", "description": "id#com.carrotsearch.ant.tasks.junit4.tests.TestBeforeClassError[0]", "failure": { "throwableClass": "java.lang.RuntimeException", "throwableString": "java.lang.RuntimeException", "stackTrace": "java.lang.RuntimeException\n\tat com.carrotsearch.ant.tasks.junit4.tests.TestBeforeClassError.beforeClass(TestBeforeClassError.java:9)\n\tat sun.reflect.NativeMethodAccessorImpl.invoke0(Native Method)\n\tat sun.reflect.NativeMethodAccessorImpl.invoke(NativeMethodAccessorImpl.java:39)\n\tat sun.reflect.DelegatingMethodAccessorImpl.invoke(DelegatingMethodAccessorImpl.java:25)\n\tat java.lang.reflect.Method.invoke(Method.java:597)\n\tat org.junit.runners.model.FrameworkMethod$1.runReflectiveCall(FrameworkMethod.java:45)\n\tat org.junit.internal.runners.model.ReflectiveCallable.run(ReflectiveCallable.java:15)\n\tat org.junit.runners.model.FrameworkMethod.invokeExplosively(FrameworkMethod.java:42)\n\tat org.junit.internal.runners.statements.RunBefores.evaluate(RunBefores.java:27)\n\tat org.junit.runners.ParentRunner.run(ParentRunner.java:300)\n\tat org.junit.runner.JUnitCore.run(JUnitCore.java:157)\n\tat com.carrotsearch.ant.tasks.junit4.slave.SlaveMain.execute(SlaveMain.java:129)\n\tat com.carrotsearch.ant.tasks.junit4.slave.SlaveMain.main(SlaveMain.java:202)\n\tat com.carrotsearch.ant.tasks.junit4.slave.SlaveMainSafe.main(SlaveMainSafe.java:12)\n", "kind": "error" } } ] }, { "slave": 0, "startTimestamp": 1331889914744, "startTimestampDate": "2012-03-16T10:25:14.744", "executionTime": 2, "description": { "id": "id#com.carrotsearch.ant.tasks.junit4.tests.TestIgnoredSuite[1]", "displayName": "com.carrotsearch.ant.tasks.junit4.tests.TestIgnoredSuite", "className": "com.carrotsearch.ant.tasks.junit4.tests.TestIgnoredSuite", "annotations": [ { "org.junit.Ignore": { "value": "" } } ], "children": [] }, "tests": [], "suiteFailures": [], "executionEvents": [] }, { "slave": 0, "startTimestamp": 1331889914756, "startTimestampDate": "2012-03-16T10:25:14.756", "executionTime": 18, "description": { "id": "id#com.carrotsearch.ant.tasks.junit4.tests.TestSysstreams[0]", "displayName": "com.carrotsearch.ant.tasks.junit4.tests.TestSysstreams", "className": "com.carrotsearch.ant.tasks.junit4.tests.TestSysstreams", "annotations": [], "children": [ { "id": "id#ok(com.carrotsearch.ant.tasks.junit4.tests.TestSysstreams)[1]", "displayName": "ok(com.carrotsearch.ant.tasks.junit4.tests.TestSysstreams)", "methodName": "ok", "className": "com.carrotsearch.ant.tasks.junit4.tests.TestSysstreams", "annotations": [ { "org.junit.Test": { "timeout": 0, "expected": "org.junit.Test$None" } } ], "children": [] }, { "id": "id#ok_sysout_syserr(com.carrotsearch.ant.tasks.junit4.tests.TestSysstreams)[1]", "displayName": "ok_sysout_syserr(com.carrotsearch.ant.tasks.junit4.tests.TestSysstreams)", "methodName": "ok_sysout_syserr", "className": "com.carrotsearch.ant.tasks.junit4.tests.TestSysstreams", "annotations": [ { "org.junit.Test": { "timeout": 0, "expected": "org.junit.Test$None" } } ], "children": [] } ] }, "tests": [ { "slave": 0, "startTimestamp": 1331889914769, "startTimestampDate": "2012-03-16T10:25:14.769", "executionTime": 1, "description": "id#ok(com.carrotsearch.ant.tasks.junit4.tests.TestSysstreams)[1]", "status": "OK", "testFailures": [] }, { "slave": 0, "startTimestamp": 1331889914771, "startTimestampDate": "2012-03-16T10:25:14.771", "executionTime": 2, "description": "id#ok_sysout_syserr(com.carrotsearch.ant.tasks.junit4.tests.TestSysstreams)[1]", "status": "OK", "testFailures": [] } ], "suiteFailures": [], "executionEvents": [ { "event": "TEST_STARTED", "description": "id#ok(com.carrotsearch.ant.tasks.junit4.tests.TestSysstreams)[1]" }, { "event": "TEST_FINISHED", "description": "id#ok(com.carrotsearch.ant.tasks.junit4.tests.TestSysstreams)[1]" }, { "event": "TEST_STARTED", "description": "id#ok_sysout_syserr(com.carrotsearch.ant.tasks.junit4.tests.TestSysstreams)[1]" }, { "event": "APPEND_STDOUT", "content": "sysout" }, { "event": "APPEND_STDERR", "content": "syserr" }, { "event": "APPEND_STDOUT", "content": "-sysout-contd." }, { "event": "APPEND_STDERR", "content": "-syserr-contd." }, { "event": "TEST_FINISHED", "description": "id#ok_sysout_syserr(com.carrotsearch.ant.tasks.junit4.tests.TestSysstreams)[1]" } ] }, { "slave": 0, "startTimestamp": 1331889914800, "startTimestampDate": "2012-03-16T10:25:14.800", "executionTime": 93, "description": { "id": "id#com.carrotsearch.ant.tasks.junit4.tests.TestStatuses[0]", "displayName": "com.carrotsearch.ant.tasks.junit4.tests.TestStatuses", "className": "com.carrotsearch.ant.tasks.junit4.tests.TestStatuses", "annotations": [], "children": [ { "id": "id#failure(com.carrotsearch.ant.tasks.junit4.tests.TestStatuses)[1]", "displayName": "failure(com.carrotsearch.ant.tasks.junit4.tests.TestStatuses)", "methodName": "failure", "className": "com.carrotsearch.ant.tasks.junit4.tests.TestStatuses", "annotations": [ { "org.junit.Test": { "timeout": 0, "expected": "org.junit.Test$None" } } ], "children": [] }, { "id": "id#error(com.carrotsearch.ant.tasks.junit4.tests.TestStatuses)[1]", "displayName": "error(com.carrotsearch.ant.tasks.junit4.tests.TestStatuses)", "methodName": "error", "className": "com.carrotsearch.ant.tasks.junit4.tests.TestStatuses", "annotations": [ { "org.junit.Test": { "timeout": 0, "expected": "org.junit.Test$None" } } ], "children": [] }, { "id": "id#ignored(com.carrotsearch.ant.tasks.junit4.tests.TestStatuses)[2]", "displayName": "ignored(com.carrotsearch.ant.tasks.junit4.tests.TestStatuses)", "methodName": "ignored", "className": "com.carrotsearch.ant.tasks.junit4.tests.TestStatuses", "annotations": [ { "org.junit.Test": { "timeout": 0, "expected": "org.junit.Test$None" } }, { "org.junit.Ignore": { "value": "" } } ], "children": [] }, { "id": "id#ok(com.carrotsearch.ant.tasks.junit4.tests.TestStatuses)[1]", "displayName": "ok(com.carrotsearch.ant.tasks.junit4.tests.TestStatuses)", "methodName": "ok", "className": "com.carrotsearch.ant.tasks.junit4.tests.TestStatuses", "annotations": [ { "org.junit.Test": { "timeout": 0, "expected": "org.junit.Test$None" } } ], "children": [] }, { "id": "id#ignored_a(com.carrotsearch.ant.tasks.junit4.tests.TestStatuses)[1]", "displayName": "ignored_a(com.carrotsearch.ant.tasks.junit4.tests.TestStatuses)", "methodName": "ignored_a", "className": "com.carrotsearch.ant.tasks.junit4.tests.TestStatuses", "annotations": [ { "org.junit.Test": { "timeout": 0, "expected": "org.junit.Test$None" } } ], "children": [] } ] }, "tests": [ { "slave": 0, "startTimestamp": 1331889914811, "startTimestampDate": "2012-03-16T10:25:14.811", "executionTime": 15, "description": "id#failure(com.carrotsearch.ant.tasks.junit4.tests.TestStatuses)[1]", "status": "FAILURE", "testFailures": [ { "throwableClass": "java.lang.AssertionError", "throwableString": "java.lang.AssertionError", "stackTrace": "java.lang.AssertionError\n\tat org.junit.Assert.fail(Assert.java:92)\n\tat org.junit.Assert.assertTrue(Assert.java:43)\n\tat org.junit.Assert.assertTrue(Assert.java:54)\n\tat com.carrotsearch.ant.tasks.junit4.tests.TestStatuses.failure(TestStatuses.java:24)\n\tat sun.reflect.NativeMethodAccessorImpl.invoke0(Native Method)\n\tat sun.reflect.NativeMethodAccessorImpl.invoke(NativeMethodAccessorImpl.java:39)\n\tat sun.reflect.DelegatingMethodAccessorImpl.invoke(DelegatingMethodAccessorImpl.java:25)\n\tat java.lang.reflect.Method.invoke(Method.java:597)\n\tat org.junit.runners.model.FrameworkMethod$1.runReflectiveCall(FrameworkMethod.java:45)\n\tat org.junit.internal.runners.model.ReflectiveCallable.run(ReflectiveCallable.java:15)\n\tat org.junit.runners.model.FrameworkMethod.invokeExplosively(FrameworkMethod.java:42)\n\tat org.junit.internal.runners.statements.InvokeMethod.evaluate(InvokeMethod.java:20)\n\tat org.junit.runners.ParentRunner.runLeaf(ParentRunner.java:263)\n\tat org.junit.runners.BlockJUnit4ClassRunner.runChild(BlockJUnit4ClassRunner.java:68)\n\tat org.junit.runners.BlockJUnit4ClassRunner.runChild(BlockJUnit4ClassRunner.java:47)\n\tat org.junit.runners.ParentRunner$3.run(ParentRunner.java:231)\n\tat org.junit.runners.ParentRunner$1.schedule(ParentRunner.java:60)\n\tat org.junit.runners.ParentRunner.runChildren(ParentRunner.java:229)\n\tat org.junit.runners.ParentRunner.access$000(ParentRunner.java:50)\n\tat org.junit.runners.ParentRunner$2.evaluate(ParentRunner.java:222)\n\tat org.junit.runners.ParentRunner.run(ParentRunner.java:300)\n\tat org.junit.runner.JUnitCore.run(JUnitCore.java:157)\n\tat com.carrotsearch.ant.tasks.junit4.slave.SlaveMain.execute(SlaveMain.java:129)\n\tat com.carrotsearch.ant.tasks.junit4.slave.SlaveMain.main(SlaveMain.java:202)\n\tat com.carrotsearch.ant.tasks.junit4.slave.SlaveMainSafe.main(SlaveMainSafe.java:12)\n", "kind": "assertion" } ] }, { "slave": 0, "startTimestamp": 1331889914829, "startTimestampDate": "2012-03-16T10:25:14.829", "executionTime": 14, "description": "id#error(com.carrotsearch.ant.tasks.junit4.tests.TestStatuses)[1]", "status": "ERROR", "testFailures": [ { "throwableClass": "java.lang.RuntimeException", "throwableString": "java.lang.RuntimeException", "stackTrace": "java.lang.RuntimeException\n\tat com.carrotsearch.ant.tasks.junit4.tests.TestStatuses.error(TestStatuses.java:29)\n\tat sun.reflect.NativeMethodAccessorImpl.invoke0(Native Method)\n\tat sun.reflect.NativeMethodAccessorImpl.invoke(NativeMethodAccessorImpl.java:39)\n\tat sun.reflect.DelegatingMethodAccessorImpl.invoke(DelegatingMethodAccessorImpl.java:25)\n\tat java.lang.reflect.Method.invoke(Method.java:597)\n\tat org.junit.runners.model.FrameworkMethod$1.runReflectiveCall(FrameworkMethod.java:45)\n\tat org.junit.internal.runners.model.ReflectiveCallable.run(ReflectiveCallable.java:15)\n\tat org.junit.runners.model.FrameworkMethod.invokeExplosively(FrameworkMethod.java:42)\n\tat org.junit.internal.runners.statements.InvokeMethod.evaluate(InvokeMethod.java:20)\n\tat org.junit.runners.ParentRunner.runLeaf(ParentRunner.java:263)\n\tat org.junit.runners.BlockJUnit4ClassRunner.runChild(BlockJUnit4ClassRunner.java:68)\n\tat org.junit.runners.BlockJUnit4ClassRunner.runChild(BlockJUnit4ClassRunner.java:47)\n\tat org.junit.runners.ParentRunner$3.run(ParentRunner.java:231)\n\tat org.junit.runners.ParentRunner$1.schedule(ParentRunner.java:60)\n\tat org.junit.runners.ParentRunner.runChildren(ParentRunner.java:229)\n\tat org.junit.runners.ParentRunner.access$000(ParentRunner.java:50)\n\tat org.junit.runners.ParentRunner$2.evaluate(ParentRunner.java:222)\n\tat org.junit.runners.ParentRunner.run(ParentRunner.java:300)\n\tat org.junit.runner.JUnitCore.run(JUnitCore.java:157)\n\tat com.carrotsearch.ant.tasks.junit4.slave.SlaveMain.execute(SlaveMain.java:129)\n\tat com.carrotsearch.ant.tasks.junit4.slave.SlaveMain.main(SlaveMain.java:202)\n\tat com.carrotsearch.ant.tasks.junit4.slave.SlaveMainSafe.main(SlaveMainSafe.java:12)\n", "kind": "error" } ] }, { "slave": 0, "startTimestamp": 1331889914845, "startTimestampDate": "2012-03-16T10:25:14.845", "executionTime": 0, "description": "id#ignored(com.carrotsearch.ant.tasks.junit4.tests.TestStatuses)[2]", "status": "IGNORED", "testFailures": [] }, { "slave": 0, "startTimestamp": 1331889914846, "startTimestampDate": "2012-03-16T10:25:14.846", "executionTime": 0, "description": "id#ok(com.carrotsearch.ant.tasks.junit4.tests.TestStatuses)[1]", "status": "OK", "testFailures": [] }, { "slave": 0, "startTimestamp": 1331889914847, "startTimestampDate": "2012-03-16T10:25:14.847", "executionTime": 45, "description": "id#ignored_a(com.carrotsearch.ant.tasks.junit4.tests.TestStatuses)[1]", "status": "IGNORED_ASSUMPTION", "testFailures": [ { "throwableClass": "org.junit.internal.AssumptionViolatedException", "throwableString": "org.junit.internal.AssumptionViolatedException: got: \u003cfalse\u003e, expected: is \u003ctrue\u003e", "stackTrace": "org.junit.internal.AssumptionViolatedException: got: \u003cfalse\u003e, expected: is \u003ctrue\u003e\n\tat org.junit.Assume.assumeThat(Assume.java:70)\n\tat org.junit.Assume.assumeTrue(Assume.java:39)\n\tat com.carrotsearch.ant.tasks.junit4.tests.TestStatuses.ignored_a(TestStatuses.java:19)\n\tat sun.reflect.NativeMethodAccessorImpl.invoke0(Native Method)\n\tat sun.reflect.NativeMethodAccessorImpl.invoke(NativeMethodAccessorImpl.java:39)\n\tat sun.reflect.DelegatingMethodAccessorImpl.invoke(DelegatingMethodAccessorImpl.java:25)\n\tat java.lang.reflect.Method.invoke(Method.java:597)\n\tat org.junit.runners.model.FrameworkMethod$1.runReflectiveCall(FrameworkMethod.java:45)\n\tat org.junit.internal.runners.model.ReflectiveCallable.run(ReflectiveCallable.java:15)\n\tat org.junit.runners.model.FrameworkMethod.invokeExplosively(FrameworkMethod.java:42)\n\tat org.junit.internal.runners.statements.InvokeMethod.evaluate(InvokeMethod.java:20)\n\tat org.junit.runners.ParentRunner.runLeaf(ParentRunner.java:263)\n\tat org.junit.runners.BlockJUnit4ClassRunner.runChild(BlockJUnit4ClassRunner.java:68)\n\tat org.junit.runners.BlockJUnit4ClassRunner.runChild(BlockJUnit4ClassRunner.java:47)\n\tat org.junit.runners.ParentRunner$3.run(ParentRunner.java:231)\n\tat org.junit.runners.ParentRunner$1.schedule(ParentRunner.java:60)\n\tat org.junit.runners.ParentRunner.runChildren(ParentRunner.java:229)\n\tat org.junit.runners.ParentRunner.access$000(ParentRunner.java:50)\n\tat org.junit.runners.ParentRunner$2.evaluate(ParentRunner.java:222)\n\tat org.junit.runners.ParentRunner.run(ParentRunner.java:300)\n\tat org.junit.runner.JUnitCore.run(JUnitCore.java:157)\n\tat com.carrotsearch.ant.tasks.junit4.slave.SlaveMain.execute(SlaveMain.java:129)\n\tat com.carrotsearch.ant.tasks.junit4.slave.SlaveMain.main(SlaveMain.java:202)\n\tat com.carrotsearch.ant.tasks.junit4.slave.SlaveMainSafe.main(SlaveMainSafe.java:12)\n", "kind": "assumption" } ] } ], "suiteFailures": [], "executionEvents": [ { "event": "TEST_STARTED", "description": "id#failure(com.carrotsearch.ant.tasks.junit4.tests.TestStatuses)[1]" }, { "event": "TEST_FAILURE", "description": "id#failure(com.carrotsearch.ant.tasks.junit4.tests.TestStatuses)[1]", "failure": { "throwableClass": "java.lang.AssertionError", "throwableString": "java.lang.AssertionError", "stackTrace": "java.lang.AssertionError\n\tat org.junit.Assert.fail(Assert.java:92)\n\tat org.junit.Assert.assertTrue(Assert.java:43)\n\tat org.junit.Assert.assertTrue(Assert.java:54)\n\tat com.carrotsearch.ant.tasks.junit4.tests.TestStatuses.failure(TestStatuses.java:24)\n\tat sun.reflect.NativeMethodAccessorImpl.invoke0(Native Method)\n\tat sun.reflect.NativeMethodAccessorImpl.invoke(NativeMethodAccessorImpl.java:39)\n\tat sun.reflect.DelegatingMethodAccessorImpl.invoke(DelegatingMethodAccessorImpl.java:25)\n\tat java.lang.reflect.Method.invoke(Method.java:597)\n\tat org.junit.runners.model.FrameworkMethod$1.runReflectiveCall(FrameworkMethod.java:45)\n\tat org.junit.internal.runners.model.ReflectiveCallable.run(ReflectiveCallable.java:15)\n\tat org.junit.runners.model.FrameworkMethod.invokeExplosively(FrameworkMethod.java:42)\n\tat org.junit.internal.runners.statements.InvokeMethod.evaluate(InvokeMethod.java:20)\n\tat org.junit.runners.ParentRunner.runLeaf(ParentRunner.java:263)\n\tat org.junit.runners.BlockJUnit4ClassRunner.runChild(BlockJUnit4ClassRunner.java:68)\n\tat org.junit.runners.BlockJUnit4ClassRunner.runChild(BlockJUnit4ClassRunner.java:47)\n\tat org.junit.runners.ParentRunner$3.run(ParentRunner.java:231)\n\tat org.junit.runners.ParentRunner$1.schedule(ParentRunner.java:60)\n\tat org.junit.runners.ParentRunner.runChildren(ParentRunner.java:229)\n\tat org.junit.runners.ParentRunner.access$000(ParentRunner.java:50)\n\tat org.junit.runners.ParentRunner$2.evaluate(ParentRunner.java:222)\n\tat org.junit.runners.ParentRunner.run(ParentRunner.java:300)\n\tat org.junit.runner.JUnitCore.run(JUnitCore.java:157)\n\tat com.carrotsearch.ant.tasks.junit4.slave.SlaveMain.execute(SlaveMain.java:129)\n\tat com.carrotsearch.ant.tasks.junit4.slave.SlaveMain.main(SlaveMain.java:202)\n\tat com.carrotsearch.ant.tasks.junit4.slave.SlaveMainSafe.main(SlaveMainSafe.java:12)\n", "kind": "assertion" } }, { "event": "TEST_FINISHED", "description": "id#failure(com.carrotsearch.ant.tasks.junit4.tests.TestStatuses)[1]" }, { "event": "TEST_STARTED", "description": "id#error(com.carrotsearch.ant.tasks.junit4.tests.TestStatuses)[1]" }, { "event": "TEST_FAILURE", "description": "id#error(com.carrotsearch.ant.tasks.junit4.tests.TestStatuses)[1]", "failure": { "throwableClass": "java.lang.RuntimeException", "throwableString": "java.lang.RuntimeException", "stackTrace": "java.lang.RuntimeException\n\tat com.carrotsearch.ant.tasks.junit4.tests.TestStatuses.error(TestStatuses.java:29)\n\tat sun.reflect.NativeMethodAccessorImpl.invoke0(Native Method)\n\tat sun.reflect.NativeMethodAccessorImpl.invoke(NativeMethodAccessorImpl.java:39)\n\tat sun.reflect.DelegatingMethodAccessorImpl.invoke(DelegatingMethodAccessorImpl.java:25)\n\tat java.lang.reflect.Method.invoke(Method.java:597)\n\tat org.junit.runners.model.FrameworkMethod$1.runReflectiveCall(FrameworkMethod.java:45)\n\tat org.junit.internal.runners.model.ReflectiveCallable.run(ReflectiveCallable.java:15)\n\tat org.junit.runners.model.FrameworkMethod.invokeExplosively(FrameworkMethod.java:42)\n\tat org.junit.internal.runners.statements.InvokeMethod.evaluate(InvokeMethod.java:20)\n\tat org.junit.runners.ParentRunner.runLeaf(ParentRunner.java:263)\n\tat org.junit.runners.BlockJUnit4ClassRunner.runChild(BlockJUnit4ClassRunner.java:68)\n\tat org.junit.runners.BlockJUnit4ClassRunner.runChild(BlockJUnit4ClassRunner.java:47)\n\tat org.junit.runners.ParentRunner$3.run(ParentRunner.java:231)\n\tat org.junit.runners.ParentRunner$1.schedule(ParentRunner.java:60)\n\tat org.junit.runners.ParentRunner.runChildren(ParentRunner.java:229)\n\tat org.junit.runners.ParentRunner.access$000(ParentRunner.java:50)\n\tat org.junit.runners.ParentRunner$2.evaluate(ParentRunner.java:222)\n\tat org.junit.runners.ParentRunner.run(ParentRunner.java:300)\n\tat org.junit.runner.JUnitCore.run(JUnitCore.java:157)\n\tat com.carrotsearch.ant.tasks.junit4.slave.SlaveMain.execute(SlaveMain.java:129)\n\tat com.carrotsearch.ant.tasks.junit4.slave.SlaveMain.main(SlaveMain.java:202)\n\tat com.carrotsearch.ant.tasks.junit4.slave.SlaveMainSafe.main(SlaveMainSafe.java:12)\n", "kind": "error" } }, { "event": "TEST_FINISHED", "description": "id#error(com.carrotsearch.ant.tasks.junit4.tests.TestStatuses)[1]" }, { "event": "TEST_IGNORED", "description": "id#ignored(com.carrotsearch.ant.tasks.junit4.tests.TestStatuses)[2]" }, { "event": "TEST_STARTED", "description": "id#ok(com.carrotsearch.ant.tasks.junit4.tests.TestStatuses)[1]" }, { "event": "TEST_FINISHED", "description": "id#ok(com.carrotsearch.ant.tasks.junit4.tests.TestStatuses)[1]" }, { "event": "TEST_STARTED", "description": "id#ignored_a(com.carrotsearch.ant.tasks.junit4.tests.TestStatuses)[1]" }, { "event": "TEST_IGNORED_ASSUMPTION", "description": "id#ignored_a(com.carrotsearch.ant.tasks.junit4.tests.TestStatuses)[1]", "failure": { "throwableClass": "org.junit.internal.AssumptionViolatedException", "throwableString": "org.junit.internal.AssumptionViolatedException: got: \u003cfalse\u003e, expected: is \u003ctrue\u003e", "stackTrace": "org.junit.internal.AssumptionViolatedException: got: \u003cfalse\u003e, expected: is \u003ctrue\u003e\n\tat org.junit.Assume.assumeThat(Assume.java:70)\n\tat org.junit.Assume.assumeTrue(Assume.java:39)\n\tat com.carrotsearch.ant.tasks.junit4.tests.TestStatuses.ignored_a(TestStatuses.java:19)\n\tat sun.reflect.NativeMethodAccessorImpl.invoke0(Native Method)\n\tat sun.reflect.NativeMethodAccessorImpl.invoke(NativeMethodAccessorImpl.java:39)\n\tat sun.reflect.DelegatingMethodAccessorImpl.invoke(DelegatingMethodAccessorImpl.java:25)\n\tat java.lang.reflect.Method.invoke(Method.java:597)\n\tat org.junit.runners.model.FrameworkMethod$1.runReflectiveCall(FrameworkMethod.java:45)\n\tat org.junit.internal.runners.model.ReflectiveCallable.run(ReflectiveCallable.java:15)\n\tat org.junit.runners.model.FrameworkMethod.invokeExplosively(FrameworkMethod.java:42)\n\tat org.junit.internal.runners.statements.InvokeMethod.evaluate(InvokeMethod.java:20)\n\tat org.junit.runners.ParentRunner.runLeaf(ParentRunner.java:263)\n\tat org.junit.runners.BlockJUnit4ClassRunner.runChild(BlockJUnit4ClassRunner.java:68)\n\tat org.junit.runners.BlockJUnit4ClassRunner.runChild(BlockJUnit4ClassRunner.java:47)\n\tat org.junit.runners.ParentRunner$3.run(ParentRunner.java:231)\n\tat org.junit.runners.ParentRunner$1.schedule(ParentRunner.java:60)\n\tat org.junit.runners.ParentRunner.runChildren(ParentRunner.java:229)\n\tat org.junit.runners.ParentRunner.access$000(ParentRunner.java:50)\n\tat org.junit.runners.ParentRunner$2.evaluate(ParentRunner.java:222)\n\tat org.junit.runners.ParentRunner.run(ParentRunner.java:300)\n\tat org.junit.runner.JUnitCore.run(JUnitCore.java:157)\n\tat com.carrotsearch.ant.tasks.junit4.slave.SlaveMain.execute(SlaveMain.java:129)\n\tat com.carrotsearch.ant.tasks.junit4.slave.SlaveMain.main(SlaveMain.java:202)\n\tat com.carrotsearch.ant.tasks.junit4.slave.SlaveMainSafe.main(SlaveMainSafe.java:12)\n", "kind": "assumption" } }, { "event": "TEST_FINISHED", "description": "id#ignored_a(com.carrotsearch.ant.tasks.junit4.tests.TestStatuses)[1]" } ] }, { "slave": 0, "startTimestamp": 1331889915015, "startTimestampDate": "2012-03-16T10:25:15.015", "executionTime": 90, "description": { "id": "id#com.carrotsearch.ant.tasks.junit4.tests.TestHierarchicalSuiteDescription[2]", "displayName": "com.carrotsearch.ant.tasks.junit4.tests.TestHierarchicalSuiteDescription", "className": "com.carrotsearch.ant.tasks.junit4.tests.TestHierarchicalSuiteDescription", "annotations": [ { "org.junit.runner.RunWith": { "value": "org.junit.runners.Suite" } }, { "org.junit.runners.Suite$SuiteClasses": { "value": [ "com.carrotsearch.ant.tasks.junit4.tests.TestHierarchicalSuiteDescription$Sub1", "com.carrotsearch.ant.tasks.junit4.tests.TestHierarchicalSuiteDescription$Sub2", "com.carrotsearch.ant.tasks.junit4.tests.TestHierarchicalSuiteDescription$Sub3" ] } } ], "children": [ { "id": "id#com.carrotsearch.ant.tasks.junit4.tests.TestHierarchicalSuiteDescription$Sub1[0]", "displayName": "com.carrotsearch.ant.tasks.junit4.tests.TestHierarchicalSuiteDescription$Sub1", "className": "com.carrotsearch.ant.tasks.junit4.tests.TestHierarchicalSuiteDescription$Sub1", "annotations": [], "children": [ { "id": "id#method1(com.carrotsearch.ant.tasks.junit4.tests.TestHierarchicalSuiteDescription$Sub1)[1]", "displayName": "method1(com.carrotsearch.ant.tasks.junit4.tests.TestHierarchicalSuiteDescription$Sub1)", "methodName": "method1", "className": "com.carrotsearch.ant.tasks.junit4.tests.TestHierarchicalSuiteDescription$Sub1", "annotations": [ { "org.junit.Test": { "timeout": 0, "expected": "org.junit.Test$None" } } ], "children": [] } ] }, { "id": "id#com.carrotsearch.ant.tasks.junit4.tests.TestHierarchicalSuiteDescription$Sub2[0]", "displayName": "com.carrotsearch.ant.tasks.junit4.tests.TestHierarchicalSuiteDescription$Sub2", "className": "com.carrotsearch.ant.tasks.junit4.tests.TestHierarchicalSuiteDescription$Sub2", "annotations": [], "children": [ { "id": "id#method1(com.carrotsearch.ant.tasks.junit4.tests.TestHierarchicalSuiteDescription$Sub2)[1]", "displayName": "method1(com.carrotsearch.ant.tasks.junit4.tests.TestHierarchicalSuiteDescription$Sub2)", "methodName": "method1", "className": "com.carrotsearch.ant.tasks.junit4.tests.TestHierarchicalSuiteDescription$Sub2", "annotations": [ { "org.junit.Test": { "timeout": 0, "expected": "org.junit.Test$None" } } ], "children": [] } ] }, { "id": "id#com.carrotsearch.ant.tasks.junit4.tests.TestHierarchicalSuiteDescription$Sub3[0]", "displayName": "com.carrotsearch.ant.tasks.junit4.tests.TestHierarchicalSuiteDescription$Sub3", "className": "com.carrotsearch.ant.tasks.junit4.tests.TestHierarchicalSuiteDescription$Sub3", "annotations": [], "children": [ { "id": "id#method1(com.carrotsearch.ant.tasks.junit4.tests.TestHierarchicalSuiteDescription$Sub3)[1]", "displayName": "method1(com.carrotsearch.ant.tasks.junit4.tests.TestHierarchicalSuiteDescription$Sub3)", "methodName": "method1", "className": "com.carrotsearch.ant.tasks.junit4.tests.TestHierarchicalSuiteDescription$Sub3", "annotations": [ { "org.junit.Test": { "timeout": 0, "expected": "org.junit.Test$None" } } ], "children": [] } ] } ] }, "tests": [ { "slave": 0, "startTimestamp": 1331889915049, "startTimestampDate": "2012-03-16T10:25:15.049", "executionTime": 0, "description": "id#method1(com.carrotsearch.ant.tasks.junit4.tests.TestHierarchicalSuiteDescription$Sub2)[1]", "status": "OK", "testFailures": [] }, { "slave": 0, "startTimestamp": 1331889915086, "startTimestampDate": "2012-03-16T10:25:15.086", "executionTime": 4, "description": "id#method1(com.carrotsearch.ant.tasks.junit4.tests.TestHierarchicalSuiteDescription$Sub3)[1]", "status": "ERROR", "testFailures": [ { "throwableClass": "java.lang.RuntimeException", "throwableString": "java.lang.RuntimeException", "stackTrace": "java.lang.RuntimeException\n\tat com.carrotsearch.ant.tasks.junit4.tests.TestHierarchicalSuiteDescription$Sub3.method1(TestHierarchicalSuiteDescription.java:40)\n\tat sun.reflect.NativeMethodAccessorImpl.invoke0(Native Method)\n\tat sun.reflect.NativeMethodAccessorImpl.invoke(NativeMethodAccessorImpl.java:39)\n\tat sun.reflect.DelegatingMethodAccessorImpl.invoke(DelegatingMethodAccessorImpl.java:25)\n\tat java.lang.reflect.Method.invoke(Method.java:597)\n\tat org.junit.runners.model.FrameworkMethod$1.runReflectiveCall(FrameworkMethod.java:45)\n\tat org.junit.internal.runners.model.ReflectiveCallable.run(ReflectiveCallable.java:15)\n\tat org.junit.runners.model.FrameworkMethod.invokeExplosively(FrameworkMethod.java:42)\n\tat org.junit.internal.runners.statements.InvokeMethod.evaluate(InvokeMethod.java:20)\n\tat org.junit.runners.ParentRunner.runLeaf(ParentRunner.java:263)\n\tat org.junit.runners.BlockJUnit4ClassRunner.runChild(BlockJUnit4ClassRunner.java:68)\n\tat org.junit.runners.BlockJUnit4ClassRunner.runChild(BlockJUnit4ClassRunner.java:47)\n\tat org.junit.runners.ParentRunner$3.run(ParentRunner.java:231)\n\tat org.junit.runners.ParentRunner$1.schedule(ParentRunner.java:60)\n\tat org.junit.runners.ParentRunner.runChildren(ParentRunner.java:229)\n\tat org.junit.runners.ParentRunner.access$000(ParentRunner.java:50)\n\tat org.junit.runners.ParentRunner$2.evaluate(ParentRunner.java:222)\n\tat org.junit.runners.ParentRunner.run(ParentRunner.java:300)\n\tat org.junit.runners.Suite.runChild(Suite.java:128)\n\tat org.junit.runners.Suite.runChild(Suite.java:24)\n\tat org.junit.runners.ParentRunner$3.run(ParentRunner.java:231)\n\tat org.junit.runners.ParentRunner$1.schedule(ParentRunner.java:60)\n\tat org.junit.runners.ParentRunner.runChildren(ParentRunner.java:229)\n\tat org.junit.runners.ParentRunner.access$000(ParentRunner.java:50)\n\tat org.junit.runners.ParentRunner$2.evaluate(ParentRunner.java:222)\n\tat org.junit.internal.runners.statements.RunAfters.evaluate(RunAfters.java:30)\n\tat org.junit.runners.ParentRunner.run(ParentRunner.java:300)\n\tat org.junit.runner.JUnitCore.run(JUnitCore.java:157)\n\tat com.carrotsearch.ant.tasks.junit4.slave.SlaveMain.execute(SlaveMain.java:129)\n\tat com.carrotsearch.ant.tasks.junit4.slave.SlaveMain.main(SlaveMain.java:202)\n\tat com.carrotsearch.ant.tasks.junit4.slave.SlaveMainSafe.main(SlaveMainSafe.java:12)\n", "kind": "error" } ] } ], "suiteFailures": [ { "throwableClass": "java.lang.RuntimeException", "throwableString": "java.lang.RuntimeException", "stackTrace": "java.lang.RuntimeException\n\tat com.carrotsearch.ant.tasks.junit4.tests.TestHierarchicalSuiteDescription$Sub1.beforeClass(TestHierarchicalSuiteDescription.java:23)\n\tat sun.reflect.NativeMethodAccessorImpl.invoke0(Native Method)\n\tat sun.reflect.NativeMethodAccessorImpl.invoke(NativeMethodAccessorImpl.java:39)\n\tat sun.reflect.DelegatingMethodAccessorImpl.invoke(DelegatingMethodAccessorImpl.java:25)\n\tat java.lang.reflect.Method.invoke(Method.java:597)\n\tat org.junit.runners.model.FrameworkMethod$1.runReflectiveCall(FrameworkMethod.java:45)\n\tat org.junit.internal.runners.model.ReflectiveCallable.run(ReflectiveCallable.java:15)\n\tat org.junit.runners.model.FrameworkMethod.invokeExplosively(FrameworkMethod.java:42)\n\tat org.junit.internal.runners.statements.RunBefores.evaluate(RunBefores.java:27)\n\tat org.junit.runners.ParentRunner.run(ParentRunner.java:300)\n\tat org.junit.runners.Suite.runChild(Suite.java:128)\n\tat org.junit.runners.Suite.runChild(Suite.java:24)\n\tat org.junit.runners.ParentRunner$3.run(ParentRunner.java:231)\n\tat org.junit.runners.ParentRunner$1.schedule(ParentRunner.java:60)\n\tat org.junit.runners.ParentRunner.runChildren(ParentRunner.java:229)\n\tat org.junit.runners.ParentRunner.access$000(ParentRunner.java:50)\n\tat org.junit.runners.ParentRunner$2.evaluate(ParentRunner.java:222)\n\tat org.junit.internal.runners.statements.RunAfters.evaluate(RunAfters.java:30)\n\tat org.junit.runners.ParentRunner.run(ParentRunner.java:300)\n\tat org.junit.runner.JUnitCore.run(JUnitCore.java:157)\n\tat com.carrotsearch.ant.tasks.junit4.slave.SlaveMain.execute(SlaveMain.java:129)\n\tat com.carrotsearch.ant.tasks.junit4.slave.SlaveMain.main(SlaveMain.java:202)\n\tat com.carrotsearch.ant.tasks.junit4.slave.SlaveMainSafe.main(SlaveMainSafe.java:12)\n", "kind": "error" }, { "throwableClass": "java.lang.RuntimeException", "throwableString": "java.lang.RuntimeException", "stackTrace": "java.lang.RuntimeException\n\tat com.carrotsearch.ant.tasks.junit4.tests.TestHierarchicalSuiteDescription$Sub2.afterClass(TestHierarchicalSuiteDescription.java:33)\n\tat sun.reflect.NativeMethodAccessorImpl.invoke0(Native Method)\n\tat sun.reflect.NativeMethodAccessorImpl.invoke(NativeMethodAccessorImpl.java:39)\n\tat sun.reflect.DelegatingMethodAccessorImpl.invoke(DelegatingMethodAccessorImpl.java:25)\n\tat java.lang.reflect.Method.invoke(Method.java:597)\n\tat org.junit.runners.model.FrameworkMethod$1.runReflectiveCall(FrameworkMethod.java:45)\n\tat org.junit.internal.runners.model.ReflectiveCallable.run(ReflectiveCallable.java:15)\n\tat org.junit.runners.model.FrameworkMethod.invokeExplosively(FrameworkMethod.java:42)\n\tat org.junit.internal.runners.statements.RunAfters.evaluate(RunAfters.java:36)\n\tat org.junit.runners.ParentRunner.run(ParentRunner.java:300)\n\tat org.junit.runners.Suite.runChild(Suite.java:128)\n\tat org.junit.runners.Suite.runChild(Suite.java:24)\n\tat org.junit.runners.ParentRunner$3.run(ParentRunner.java:231)\n\tat org.junit.runners.ParentRunner$1.schedule(ParentRunner.java:60)\n\tat org.junit.runners.ParentRunner.runChildren(ParentRunner.java:229)\n\tat org.junit.runners.ParentRunner.access$000(ParentRunner.java:50)\n\tat org.junit.runners.ParentRunner$2.evaluate(ParentRunner.java:222)\n\tat org.junit.internal.runners.statements.RunAfters.evaluate(RunAfters.java:30)\n\tat org.junit.runners.ParentRunner.run(ParentRunner.java:300)\n\tat org.junit.runner.JUnitCore.run(JUnitCore.java:157)\n\tat com.carrotsearch.ant.tasks.junit4.slave.SlaveMain.execute(SlaveMain.java:129)\n\tat com.carrotsearch.ant.tasks.junit4.slave.SlaveMain.main(SlaveMain.java:202)\n\tat com.carrotsearch.ant.tasks.junit4.slave.SlaveMainSafe.main(SlaveMainSafe.java:12)\n", "kind": "error" }, { "throwableClass": "java.lang.RuntimeException", "throwableString": "java.lang.RuntimeException", "stackTrace": "java.lang.RuntimeException\n\tat com.carrotsearch.ant.tasks.junit4.tests.TestHierarchicalSuiteDescription.afterClass(TestHierarchicalSuiteDescription.java:46)\n\tat sun.reflect.NativeMethodAccessorImpl.invoke0(Native Method)\n\tat sun.reflect.NativeMethodAccessorImpl.invoke(NativeMethodAccessorImpl.java:39)\n\tat sun.reflect.DelegatingMethodAccessorImpl.invoke(DelegatingMethodAccessorImpl.java:25)\n\tat java.lang.reflect.Method.invoke(Method.java:597)\n\tat org.junit.runners.model.FrameworkMethod$1.runReflectiveCall(FrameworkMethod.java:45)\n\tat org.junit.internal.runners.model.ReflectiveCallable.run(ReflectiveCallable.java:15)\n\tat org.junit.runners.model.FrameworkMethod.invokeExplosively(FrameworkMethod.java:42)\n\tat org.junit.internal.runners.statements.RunAfters.evaluate(RunAfters.java:36)\n\tat org.junit.runners.ParentRunner.run(ParentRunner.java:300)\n\tat org.junit.runner.JUnitCore.run(JUnitCore.java:157)\n\tat com.carrotsearch.ant.tasks.junit4.slave.SlaveMain.execute(SlaveMain.java:129)\n\tat com.carrotsearch.ant.tasks.junit4.slave.SlaveMain.main(SlaveMain.java:202)\n\tat com.carrotsearch.ant.tasks.junit4.slave.SlaveMainSafe.main(SlaveMainSafe.java:12)\n", "kind": "error" } ], "executionEvents": [ { "event": "TEST_FAILURE", "description": "id#com.carrotsearch.ant.tasks.junit4.tests.TestHierarchicalSuiteDescription$Sub1[0]", "failure": { "throwableClass": "java.lang.RuntimeException", "throwableString": "java.lang.RuntimeException", "stackTrace": "java.lang.RuntimeException\n\tat com.carrotsearch.ant.tasks.junit4.tests.TestHierarchicalSuiteDescription$Sub1.beforeClass(TestHierarchicalSuiteDescription.java:23)\n\tat sun.reflect.NativeMethodAccessorImpl.invoke0(Native Method)\n\tat sun.reflect.NativeMethodAccessorImpl.invoke(NativeMethodAccessorImpl.java:39)\n\tat sun.reflect.DelegatingMethodAccessorImpl.invoke(DelegatingMethodAccessorImpl.java:25)\n\tat java.lang.reflect.Method.invoke(Method.java:597)\n\tat org.junit.runners.model.FrameworkMethod$1.runReflectiveCall(FrameworkMethod.java:45)\n\tat org.junit.internal.runners.model.ReflectiveCallable.run(ReflectiveCallable.java:15)\n\tat org.junit.runners.model.FrameworkMethod.invokeExplosively(FrameworkMethod.java:42)\n\tat org.junit.internal.runners.statements.RunBefores.evaluate(RunBefores.java:27)\n\tat org.junit.runners.ParentRunner.run(ParentRunner.java:300)\n\tat org.junit.runners.Suite.runChild(Suite.java:128)\n\tat org.junit.runners.Suite.runChild(Suite.java:24)\n\tat org.junit.runners.ParentRunner$3.run(ParentRunner.java:231)\n\tat org.junit.runners.ParentRunner$1.schedule(ParentRunner.java:60)\n\tat org.junit.runners.ParentRunner.runChildren(ParentRunner.java:229)\n\tat org.junit.runners.ParentRunner.access$000(ParentRunner.java:50)\n\tat org.junit.runners.ParentRunner$2.evaluate(ParentRunner.java:222)\n\tat org.junit.internal.runners.statements.RunAfters.evaluate(RunAfters.java:30)\n\tat org.junit.runners.ParentRunner.run(ParentRunner.java:300)\n\tat org.junit.runner.JUnitCore.run(JUnitCore.java:157)\n\tat com.carrotsearch.ant.tasks.junit4.slave.SlaveMain.execute(SlaveMain.java:129)\n\tat com.carrotsearch.ant.tasks.junit4.slave.SlaveMain.main(SlaveMain.java:202)\n\tat com.carrotsearch.ant.tasks.junit4.slave.SlaveMainSafe.main(SlaveMainSafe.java:12)\n", "kind": "error" } }, { "event": "TEST_STARTED", "description": "id#method1(com.carrotsearch.ant.tasks.junit4.tests.TestHierarchicalSuiteDescription$Sub2)[1]" }, { "event": "TEST_FINISHED", "description": "id#method1(com.carrotsearch.ant.tasks.junit4.tests.TestHierarchicalSuiteDescription$Sub2)[1]" }, { "event": "TEST_FAILURE", "description": "id#com.carrotsearch.ant.tasks.junit4.tests.TestHierarchicalSuiteDescription$Sub2[0]", "failure": { "throwableClass": "java.lang.RuntimeException", "throwableString": "java.lang.RuntimeException", "stackTrace": "java.lang.RuntimeException\n\tat com.carrotsearch.ant.tasks.junit4.tests.TestHierarchicalSuiteDescription$Sub2.afterClass(TestHierarchicalSuiteDescription.java:33)\n\tat sun.reflect.NativeMethodAccessorImpl.invoke0(Native Method)\n\tat sun.reflect.NativeMethodAccessorImpl.invoke(NativeMethodAccessorImpl.java:39)\n\tat sun.reflect.DelegatingMethodAccessorImpl.invoke(DelegatingMethodAccessorImpl.java:25)\n\tat java.lang.reflect.Method.invoke(Method.java:597)\n\tat org.junit.runners.model.FrameworkMethod$1.runReflectiveCall(FrameworkMethod.java:45)\n\tat org.junit.internal.runners.model.ReflectiveCallable.run(ReflectiveCallable.java:15)\n\tat org.junit.runners.model.FrameworkMethod.invokeExplosively(FrameworkMethod.java:42)\n\tat org.junit.internal.runners.statements.RunAfters.evaluate(RunAfters.java:36)\n\tat org.junit.runners.ParentRunner.run(ParentRunner.java:300)\n\tat org.junit.runners.Suite.runChild(Suite.java:128)\n\tat org.junit.runners.Suite.runChild(Suite.java:24)\n\tat org.junit.runners.ParentRunner$3.run(ParentRunner.java:231)\n\tat org.junit.runners.ParentRunner$1.schedule(ParentRunner.java:60)\n\tat org.junit.runners.ParentRunner.runChildren(ParentRunner.java:229)\n\tat org.junit.runners.ParentRunner.access$000(ParentRunner.java:50)\n\tat org.junit.runners.ParentRunner$2.evaluate(ParentRunner.java:222)\n\tat org.junit.internal.runners.statements.RunAfters.evaluate(RunAfters.java:30)\n\tat org.junit.runners.ParentRunner.run(ParentRunner.java:300)\n\tat org.junit.runner.JUnitCore.run(JUnitCore.java:157)\n\tat com.carrotsearch.ant.tasks.junit4.slave.SlaveMain.execute(SlaveMain.java:129)\n\tat com.carrotsearch.ant.tasks.junit4.slave.SlaveMain.main(SlaveMain.java:202)\n\tat com.carrotsearch.ant.tasks.junit4.slave.SlaveMainSafe.main(SlaveMainSafe.java:12)\n", "kind": "error" } }, { "event": "TEST_STARTED", "description": "id#method1(com.carrotsearch.ant.tasks.junit4.tests.TestHierarchicalSuiteDescription$Sub3)[1]" }, { "event": "TEST_FAILURE", "description": "id#method1(com.carrotsearch.ant.tasks.junit4.tests.TestHierarchicalSuiteDescription$Sub3)[1]", "failure": { "throwableClass": "java.lang.RuntimeException", "throwableString": "java.lang.RuntimeException", "stackTrace": "java.lang.RuntimeException\n\tat com.carrotsearch.ant.tasks.junit4.tests.TestHierarchicalSuiteDescription$Sub3.method1(TestHierarchicalSuiteDescription.java:40)\n\tat sun.reflect.NativeMethodAccessorImpl.invoke0(Native Method)\n\tat sun.reflect.NativeMethodAccessorImpl.invoke(NativeMethodAccessorImpl.java:39)\n\tat sun.reflect.DelegatingMethodAccessorImpl.invoke(DelegatingMethodAccessorImpl.java:25)\n\tat java.lang.reflect.Method.invoke(Method.java:597)\n\tat org.junit.runners.model.FrameworkMethod$1.runReflectiveCall(FrameworkMethod.java:45)\n\tat org.junit.internal.runners.model.ReflectiveCallable.run(ReflectiveCallable.java:15)\n\tat org.junit.runners.model.FrameworkMethod.invokeExplosively(FrameworkMethod.java:42)\n\tat org.junit.internal.runners.statements.InvokeMethod.evaluate(InvokeMethod.java:20)\n\tat org.junit.runners.ParentRunner.runLeaf(ParentRunner.java:263)\n\tat org.junit.runners.BlockJUnit4ClassRunner.runChild(BlockJUnit4ClassRunner.java:68)\n\tat org.junit.runners.BlockJUnit4ClassRunner.runChild(BlockJUnit4ClassRunner.java:47)\n\tat org.junit.runners.ParentRunner$3.run(ParentRunner.java:231)\n\tat org.junit.runners.ParentRunner$1.schedule(ParentRunner.java:60)\n\tat org.junit.runners.ParentRunner.runChildren(ParentRunner.java:229)\n\tat org.junit.runners.ParentRunner.access$000(ParentRunner.java:50)\n\tat org.junit.runners.ParentRunner$2.evaluate(ParentRunner.java:222)\n\tat org.junit.runners.ParentRunner.run(ParentRunner.java:300)\n\tat org.junit.runners.Suite.runChild(Suite.java:128)\n\tat org.junit.runners.Suite.runChild(Suite.java:24)\n\tat org.junit.runners.ParentRunner$3.run(ParentRunner.java:231)\n\tat org.junit.runners.ParentRunner$1.schedule(ParentRunner.java:60)\n\tat org.junit.runners.ParentRunner.runChildren(ParentRunner.java:229)\n\tat org.junit.runners.ParentRunner.access$000(ParentRunner.java:50)\n\tat org.junit.runners.ParentRunner$2.evaluate(ParentRunner.java:222)\n\tat org.junit.internal.runners.statements.RunAfters.evaluate(RunAfters.java:30)\n\tat org.junit.runners.ParentRunner.run(ParentRunner.java:300)\n\tat org.junit.runner.JUnitCore.run(JUnitCore.java:157)\n\tat com.carrotsearch.ant.tasks.junit4.slave.SlaveMain.execute(SlaveMain.java:129)\n\tat com.carrotsearch.ant.tasks.junit4.slave.SlaveMain.main(SlaveMain.java:202)\n\tat com.carrotsearch.ant.tasks.junit4.slave.SlaveMainSafe.main(SlaveMainSafe.java:12)\n", "kind": "error" } }, { "event": "TEST_FINISHED", "description": "id#method1(com.carrotsearch.ant.tasks.junit4.tests.TestHierarchicalSuiteDescription$Sub3)[1]" }, { "event": "SUITE_FAILURE", "description": "id#com.carrotsearch.ant.tasks.junit4.tests.TestHierarchicalSuiteDescription[2]", "failure": { "throwableClass": "java.lang.RuntimeException", "throwableString": "java.lang.RuntimeException", "stackTrace": "java.lang.RuntimeException\n\tat com.carrotsearch.ant.tasks.junit4.tests.TestHierarchicalSuiteDescription.afterClass(TestHierarchicalSuiteDescription.java:46)\n\tat sun.reflect.NativeMethodAccessorImpl.invoke0(Native Method)\n\tat sun.reflect.NativeMethodAccessorImpl.invoke(NativeMethodAccessorImpl.java:39)\n\tat sun.reflect.DelegatingMethodAccessorImpl.invoke(DelegatingMethodAccessorImpl.java:25)\n\tat java.lang.reflect.Method.invoke(Method.java:597)\n\tat org.junit.runners.model.FrameworkMethod$1.runReflectiveCall(FrameworkMethod.java:45)\n\tat org.junit.internal.runners.model.ReflectiveCallable.run(ReflectiveCallable.java:15)\n\tat org.junit.runners.model.FrameworkMethod.invokeExplosively(FrameworkMethod.java:42)\n\tat org.junit.internal.runners.statements.RunAfters.evaluate(RunAfters.java:36)\n\tat org.junit.runners.ParentRunner.run(ParentRunner.java:300)\n\tat org.junit.runner.JUnitCore.run(JUnitCore.java:157)\n\tat com.carrotsearch.ant.tasks.junit4.slave.SlaveMain.execute(SlaveMain.java:129)\n\tat com.carrotsearch.ant.tasks.junit4.slave.SlaveMain.main(SlaveMain.java:202)\n\tat com.carrotsearch.ant.tasks.junit4.slave.SlaveMainSafe.main(SlaveMainSafe.java:12)\n", "kind": "error" } } ] } ], "slaves": { "0": { "id": 0, "jvmName": "Java HotSpot(TM) 64-Bit Server VM, 16.3-b01", "charset": "UTF-8", "commandLine": "/home/dweiss/Applications/java/jdk1.6.0_20/jre/bin/java -Drt.prefix\u003drt -Drt.seed\u003dB19FBD1BB1231191 -classpath /home/dweiss/carrot2/carrotsearch.labs/randomizedtesting/integration-ant/ant-junit4/target/test-classes:/home/dweiss/carrot2/carrotsearch.labs/randomizedtesting/integration-ant/ant-junit4/target/dependency/junit-4.10.jar:/home/dweiss/carrot2/carrotsearch.labs/randomizedtesting/integration-ant/ant-junit4/target/classes:/home/dweiss/.m2/repository/com/google/guava/guava/10.0.1/guava-10.0.1.jar:/home/dweiss/carrot2/carrotsearch.labs/randomizedtesting/runner/target/classes:/home/dweiss/.m2/repository/com/google/code/gson/gson/2.0/gson-2.0.jar:/home/dweiss/.m2/repository/commons-io/commons-io/2.1/commons-io-2.1.jar com.carrotsearch.ant.tasks.junit4.slave.SlaveMainSafe -flush @/home/dweiss/carrot2/carrotsearch.labs/randomizedtesting/integration-ant/ant-junit4/target/test-classes/junit4-slave-04421343907870964512.suites", "systemProperties": { "file.encoding": "UTF-8", "file.encoding.pkg": "sun.io", "file.separator": "/", "java.awt.graphicsenv": "sun.awt.X11GraphicsEnvironment", "java.awt.printerjob": "sun.print.PSPrinterJob", "java.class.path": "/home/dweiss/carrot2/carrotsearch.labs/randomizedtesting/integration-ant/ant-junit4/target/test-classes:/home/dweiss/carrot2/carrotsearch.labs/randomizedtesting/integration-ant/ant-junit4/target/dependency/junit-4.10.jar:/home/dweiss/carrot2/carrotsearch.labs/randomizedtesting/integration-ant/ant-junit4/target/classes:/home/dweiss/.m2/repository/com/google/guava/guava/10.0.1/guava-10.0.1.jar:/home/dweiss/carrot2/carrotsearch.labs/randomizedtesting/runner/target/classes:/home/dweiss/.m2/repository/com/google/code/gson/gson/2.0/gson-2.0.jar:/home/dweiss/.m2/repository/commons-io/commons-io/2.1/commons-io-2.1.jar", "java.class.version": "50.0", "java.endorsed.dirs": "/home/dweiss/Applications/java/jdk1.6.0_20/jre/lib/endorsed", "java.ext.dirs": "/home/dweiss/Applications/java/jdk1.6.0_20/jre/lib/ext:/usr/java/packages/lib/ext", "java.home": "/home/dweiss/Applications/java/jdk1.6.0_20/jre", "java.io.tmpdir": "/tmp", "java.library.path": "/home/dweiss/Applications/java/jdk1.6.0_20/jre/lib/amd64/server:/home/dweiss/Applications/java/jdk1.6.0_20/jre/lib/amd64:/home/dweiss/Applications/java/jdk1.6.0_20/jre/../lib/amd64:/usr/lib/jvm/java-6-openjdk/jre/lib/amd64/server:/usr/lib/jvm/java-6-openjdk/jre/lib/amd64:/usr/lib/jvm/java-6-openjdk/jre/../lib/amd64:/usr/java/packages/lib/amd64:/usr/lib64:/lib64:/lib:/usr/lib", "java.runtime.name": "Java(TM) SE Runtime Environment", "java.runtime.version": "1.6.0_20-b02", "java.specification.name": "Java Platform API Specification", "java.specification.vendor": "Sun Microsystems Inc.", "java.specification.version": "1.6", "java.vendor": "Sun Microsystems Inc.", "java.vendor.url": "http://java.sun.com/", "java.vendor.url.bug": "http://java.sun.com/cgi-bin/bugreport.cgi", "java.version": "1.6.0_20", "java.vm.info": "mixed mode", "java.vm.name": "Java HotSpot(TM) 64-Bit Server VM", "java.vm.specification.name": "Java Virtual Machine Specification", "java.vm.specification.vendor": "Sun Microsystems Inc.", "java.vm.specification.version": "1.0", "java.vm.vendor": "Sun Microsystems Inc.", "java.vm.version": "16.3-b01", "junit4.memory.total": "62259200", "junit4.processors": "2", "line.separator": "\n", "os.arch": "amd64", "os.name": "Linux", "os.version": "3.0.0-16-generic", "path.separator": ":", "rt.prefix": "rt", "rt.seed": "B19FBD1BB1231191", "sun.arch.data.model": "64", "sun.boot.class.path": "/home/dweiss/Applications/java/jdk1.6.0_20/jre/lib/resources.jar:/home/dweiss/Applications/java/jdk1.6.0_20/jre/lib/rt.jar:/home/dweiss/Applications/java/jdk1.6.0_20/jre/lib/sunrsasign.jar:/home/dweiss/Applications/java/jdk1.6.0_20/jre/lib/jsse.jar:/home/dweiss/Applications/java/jdk1.6.0_20/jre/lib/jce.jar:/home/dweiss/Applications/java/jdk1.6.0_20/jre/lib/charsets.jar:/home/dweiss/Applications/java/jdk1.6.0_20/jre/classes", "sun.boot.library.path": "/home/dweiss/Applications/java/jdk1.6.0_20/jre/lib/amd64", "sun.cpu.endian": "little", "sun.cpu.isalist": "", "sun.desktop": "gnome", "sun.io.unicode.encoding": "UnicodeLittle", "sun.java.launcher": "SUN_STANDARD", "sun.jnu.encoding": "UTF-8", "sun.management.compiler": "HotSpot 64-Bit Server Compiler", "sun.os.patch.level": "unknown", "user.country": "US", "user.dir": "/home/dweiss/carrot2/carrotsearch.labs/randomizedtesting/integration-ant/ant-junit4/target/test-classes/S0", "user.home": "/home/dweiss", "user.language": "en", "user.name": "dweiss", "user.timezone": "" } } } });randomizedtesting-release-2.1.6/junit4-ant/src/main/resources/com/carrotsearch/junit4/000077500000000000000000000000001235451432000310645ustar00rootroot00000000000000randomizedtesting-release-2.1.6/junit4-ant/src/main/resources/com/carrotsearch/junit4/antlib.xml000066400000000000000000000033061235451432000330610ustar00rootroot00000000000000 randomizedtesting-release-2.1.6/junit4-ant/src/native/000077500000000000000000000000001235451432000227415ustar00rootroot00000000000000com_carrotsearch_ant_tasks_junit4_tests_Crash.h000066400000000000000000000010531235451432000342560ustar00rootroot00000000000000randomizedtesting-release-2.1.6/junit4-ant/src/native/* DO NOT EDIT THIS FILE - it is machine generated */ #include /* Header for class com_carrotsearch_ant_tasks_junit4_tests_Crash */ #ifndef _Included_com_carrotsearch_ant_tasks_junit4_tests_Crash #define _Included_com_carrotsearch_ant_tasks_junit4_tests_Crash #ifdef __cplusplus extern "C" { #endif /* * Class: com_carrotsearch_ant_tasks_junit4_tests_Crash * Method: crashMe * Signature: ()V */ JNIEXPORT void JNICALL Java_com_carrotsearch_ant_tasks_junit4_tests_Crash_crashMe (JNIEnv *, jclass); #ifdef __cplusplus } #endif #endif randomizedtesting-release-2.1.6/junit4-ant/src/native/compile-mac.sh000077500000000000000000000002301235451432000254610ustar00rootroot00000000000000#!/bin/bash CFLAGS="-I /System/Library/Frameworks/JavaVM.framework/Headers/" gcc -m64 ${CFLAGS} -shared -static -fPIC crash.c -o lib/libcrash64.dylib randomizedtesting-release-2.1.6/junit4-ant/src/native/compile.sh000077500000000000000000000010011235451432000247200ustar00rootroot00000000000000#!/bin/bash CFLAGS="-I ${JAVA_HOME}/include -I ${JAVA_HOME}/include/linux -I ${JAVA_HOME}/include/win32" # Linux, 64-bit. gcc -m64 ${CFLAGS} -fPIC -c crash.c ld -shared -static -o lib/libcrash64.so *.o # Linux, 32-bit. gcc -m32 ${CFLAGS} -fPIC -c crash.c ld -melf_i386 -shared -static -o lib/libcrash.so *.o # Windows, 32-bit rm -f *.o i686-w64-mingw32-gcc ${CFLAGS} -shared -o lib/crash.dll crash.c # Windows, 64-bit rm -f *.o x86_64-w64-mingw32-gcc ${CFLAGS} -shared -o lib/crash64.dll crash.c rm -f *.o randomizedtesting-release-2.1.6/junit4-ant/src/native/crash.c000066400000000000000000000003331235451432000242040ustar00rootroot00000000000000 #include "com_carrotsearch_ant_tasks_junit4_tests_Crash.h" #include "stdio.h" JNIEXPORT void JNICALL Java_com_carrotsearch_ant_tasks_junit4_tests_Crash_crashMe (JNIEnv * env, jclass clazz) { ((char*) 0)[0] = 0; } randomizedtesting-release-2.1.6/junit4-ant/src/proguard/000077500000000000000000000000001235451432000232765ustar00rootroot00000000000000randomizedtesting-release-2.1.6/junit4-ant/src/proguard/rules.pro000066400000000000000000000013351235451432000251540ustar00rootroot00000000000000 -dontoptimize -dontnote -dontwarn -renamepackage com.google=>com.carrotsearch.ant.tasks.junit4.dependencies -renamepackage org.objectweb=>com.carrotsearch.ant.tasks.junit4.dependencies -renamepackage org.apache=>com.carrotsearch.ant.tasks.junit4.dependencies -renamepackage org.simpleframework=>com.carrotsearch.ant.tasks.junit4.dependencies -renamepackage com.carrotsearch.randomizedtesting=>com.carrotsearch.ant.tasks.junit4.dependencies -repackageclasses com.carrotsearch.ant.tasks.junit4.dependencies -keepattributes SourceFile,LineNumberTable -keepattributes *Annotation* -keep class com.carrotsearch.ant.** { ; ; } -keep class org.simpleframework.** { ; ; }randomizedtesting-release-2.1.6/junit4-ant/src/tasks/000077500000000000000000000000001235451432000226005ustar00rootroot00000000000000randomizedtesting-release-2.1.6/junit4-ant/src/tasks/Tasks/000077500000000000000000000000001235451432000236655ustar00rootroot00000000000000randomizedtesting-release-2.1.6/junit4-ant/src/tasks/Tasks/junit4.html000066400000000000000000000743521235451432000260030ustar00rootroot00000000000000 JUnit4 Task

JUnit4

Description

This task runs tests from the JUnit testing framework in versions 4.10 and above. It to some extent mimics the style of the default ANT's junit task, but adds the following features:

  • ability to run tests in multiple forked JVMs (isolated JVMs),
  • ability to load-balance tests based on previous execution history or job-stealing,
  • seamless integration with randomized runner to support a global seed for randomized tests and proper seed reporting,
  • Synchronized and decluttered console output from child JVMs,
  • Built-in reporting to HTML, JSON and various forms of plain text.

Note: The latest version of the JUnit framework can be found at http://www.junit.org. This task has been tested with JUnit 4.10 and later. Appropriate junit*.jar must be available in the task's classpath and in the tested code's classpath. See the examples below.

External references: More information about randomized testing.

Parameters

junit4 attempts to be a drop-in replacement for ANT's default junit task, but so attributes that make little sense have been deprecated and are ignored. Attributes specific to junit4 are highlighted in light green.

Attribute Description Required
printsummary Prints the summary of all executed, ignored and failed tests after all suites have been executed. To get per-suite summaries, configure a console report properly (see below). No; default is on.
fork Not used. ANT-junit drop-in compatibility only. Tests are always forked. --
forkmode Not used. ANT-junit drop-in compatibility only. Tests are always forked into one more more forked JVMs. Each suite is executed entirely on a single JVM. --
haltonerror Not used. ANT-junit drop-in compatibility only. Use haltonfailure which handles both errors and failures. --
errorproperty Not used. ANT-junit drop-in compatibility only. Use failureproperty which handles both errors and failures. --
haltonfailure Stop the build process if a test fails (errors are considered failures as well). No; default is on (ANT's junit has the default set to 'off').
failureproperty The name of a property to set in the event of a failure (errors are considered failures as well). No.
filtertrace Not used. ANT-junit drop-in compatibility only. Reports may provide their own filtering capabilities. --
timeout Not used. ANT-junit drop-in compatibility only. Test runners provide their own timeout facilities. --
maxmemory Maximum amount of memory to allocate to each forked VM (be careful if using lots of forks). Note: If you get java.lang.OutOfMemoryError: Java heap space in some of your tests then you need to raise the size like maxmemory="128m" No
jvm The command used to invoke the forked java virtual machines, the default is 'java'. The command is resolved by java.lang.Runtime.exec(). No; default is java.
dir The directory in which to invoke the forked JVMs in. This is by default the project's basedir. Because multiple JVMs may clash if they are generating files in the current working directory, one can use per-JVM directory by setting isolateWorkingDirectories attribute to true; in such case each JVM gets a sub-directory under whatever dir is defined. No
isolateWorkingDirectories If true current working directories are isolated for each forked JVM. See dir attribute too. No; default is true.
newenvironment Do not propagate the old environment when new environment variables are specified. No; default is false.
includeantruntime Not used. ANT-junit drop-in compatibility only. --
showoutput Not used. ANT-junit drop-in compatibility only. Configure console reports appropriately. --
outputtoformatters Not used. ANT-junit drop-in compatibility only. Configure console reports appropriately. --
tempdir Specify where to store temporary files. These temporary files include a list of suites passed to each slave JVM so it is usually wise to just leave this attribute unset - the default is to take the value of the dir attribute or the project's basedir. No
reloading Not used. ANT-junit drop-in compatibility only. --
clonevm Not used. ANT-junit drop-in compatibility only. --
logfailedtests Not used. ANT-junit drop-in compatibility only. Configure console reports appropriately to get just the failing tests, their output etc. --
enableTestListenerEvents Not used. ANT-junit drop-in compatibility only. --
parallelism The number of parallel slaves. Can be set to a constant max for the maximum number of cores returned from Runtime.availableProcessors or auto for sensible defaults depending on the number of cores.

Note: this setting forks physical JVM processes so it multiplies the requirements for heap memory, IO, etc.

No; Can be set to any integer or: 'max', 'auto'. The default is '1' (sequential execution in a forked JVM).
dynamicAssignmentRatio Specifies the ratio of suites moved to dynamic assignment list (job-stealing). A dynamic assignment list dispatches suites to the first idle slave JVM. Theoretically this is an optimal strategy, but it is usually better to have some static assignments to avoid communication costs.

A ratio of 0 means only static assignments are used. A ratio of 1 means only dynamic assignments are used.

The list of dynamic assignments is sorted by decreasing cost (always) and is inherently prone to race conditions in distributing suites. Should there be an error based on suite-dependency it will not be directly repeatable. In such case use the per-slave-jvm list of suites file dumped to disk for each slave JVM. See leaveTemporary attribute.

No; default is '0.25' (25% of all suites are assigned dynamically).
seed Specify random seed for anything that is randomized in junit4. The order of suites execution and suite-JVM assignments are a result of this seed for example.

The master seed is also passed to slave JVMs as a system property (to bootstrap randomized runner).

No; default is a randomly generated seed.
prefix Initializes custom prefix for all randomized runner properties. This must be consistent across all junit4 invocations if done from the same classpath. Use only when REALLY needed. No; default is randomized runner's prefix.
shuffleOnSlave Predictably shuffle tests order after balancing. This will help in spreading lighter and heavier tests over a single slave's execution timeline while still keeping the same tests order depending on the seed. See nested elements for configuring load balancers. No; the default is 'true'.
leaveTemporary Leave temporary junit4 files after the task quits. This can be used to trace the exact order of suites executed on each forked JVM for example. No; default is 'false'.
jvmOutputAction What should be done on unexpected JVM output? JVM may write directly to the original descriptors, bypassing redirections of System.out and System.err. Typically, these messages will be important and should fail the build (permgen space exceeded, compiler errors, crash dumps). However, certain legitimate logs (gc activity, class loading logs) are also printed to these streams so sometimes the output can be ignored.

Allowed values (any comma-delimited combination of): ignore, pipe, fail, warn.

No; default is 'pipe,warn'.
sysouts If set to true, any sysout and syserr calls will be written to original output and error streams (and in effect will appear as "jvm output". By default sysout and syserrs are captured and proxied to the event stream to be synchronized with other test events (and properly handled by reports) but occasionally one may want to synchronize them with direct JVM output (to synchronize with compiler output or GC output for example).

See examples below on examples of capturing full JVM output.

No; default is 'false'.
heartbeat A duration (in seconds) before an event is dispatched about forked JVM inactivity. This can be useful to report hung or very long tests. Heartbeat information will include an approximate location inside the non-responding JVM (suite or test case). No; default is '0'.
uniqueSuiteNames Allow or disallow duplicate suite names in resource collections. By default this option is true because certain ANT-compatible report types (like XML reports) will have a problem with duplicate suite names (will overwrite files). No; default is 'true'.
ifNoTests Defines the behavior when no tests were executed successfully or failed (either there were no tests at all or all of them were filtered out). One of the following enum constants: 'ignore', 'warn' or 'fail'. No; default is 'ignore'.

Nested Elements

The <junit4> task supports a nested elements. Some of them are compatible with ANT's default <junit> task while others are unique to <junit4>.

Specifying classpath for tests

The <classpath> element represents a PATH like structure to be used for each forked JVM. Note that classpath should include suiteable junit*.jar, otherwise your tests wont run.

Specifying test suite classes

Unlike standard <junit> task, <junit4> defines suite classes as resources to .class files. These resources can originate from any resource collection and there can be any number of resource collections with such resources. For example this definition includes all suite classes from a ZIP file (JAR file), excluding nested classes:

jvmarg

Additional parameters may be passed to the new JVM via nested <jvmarg> elements. For example:


would run the JVM with a serial garbage collector on HotSpot JVM.

sysproperty

Use nested <sysproperty> elements to specify system properties required by the tests. These properties will be made available to the forked JVMs during their execution. The attributes for this element are the same as for environment variables.

An extended attribute <ignoreEmpty> is supported which, if defined, causes the property NOT to be defined in the forked JVM (as opposed to passing an empty property value).

would run the test in ANT's VM and make the project's basedir property available to the test (note the current working directory of a forked JVM will not be the basedir typically).

syspropertyset

You can specify a set of properties to be passed to the target JVM as system properties with syspropertysets. This target behaves much like the default in ANT but allows a dynamic set of (remapped) properties to be resolved at runtime. Similar to sysproperty, this tag also supports ignoreEmpty attribute to work around bugs with local properties in ANT.

env

It is possible to specify environment variables to pass to the forked VM via nested <env> elements. For a description of the <env> element's attributes, see the description in the exec task.

bootclasspath

The location of bootstrap class files can be specified using this PATH like structure.

assertions

You can control enablement of Java 1.4 assertions with an <assertions> subelement.

listeners and reports

There is no notion of "reports" in junit4. Reports are just listeners that attach to the even stream and can produce something (to the console, file or otherwise). You can also attach your own listeners if you like (although you'd have to peek at the code of existing listeners to get the feeling how this is done -- communication is via events not interfaces).

report-text

There are a few predefined listeners to choose from. By far the most common will be report-text which produces console output (or plain text file). A plain text report configuration may look like this:

This listener supports stack trace filtering to reduce verbosity (console output, for example). For production or integration builds, it is recommended to keep the full stacks. For developer runs, the default set of filters (enabled by default) can declutter the output a bit. An example stack trace filter, with default options and two custom filters, is shown below.

The level of verbosity of the output can be fine-tuned to one's needs by disabling or enabling test statuses and suite summaries or each test's output. Experimenting highly recommended.

report-ant-xml

Another listener is report-ant-xml which can produce XML files suitable for junitreport task (although we highly recommend using the built-in JSON report.

report-json

Yet another built-in listener is producing a modern JSON output with test data and an accompanying HTML5 file for visualizing it:

An example of a HTML5 report produced by the above can be seen here, for example.

Load balancing of test suites

Suites can be scattered across forked JVMs randomly or using a greedy load-balancing algorithm (and followed by job-stealing if needed). For load balancing, previous execution statistics will be needed. These statistics should ideally come from a single machine and multiple executions so that they average the influence of the environment etc.

A dedicated listener is used to collect and update statistics. The configuration below shows both the listener and a balancer configuration. The balancer uses multiple sources for collecting statistics (for example precomputed statistics and previous local runs):

Capturing original JVM output

JUnit4 has been designed to run reports and aggregation of test events on the master JVM, not on the forked JVMs. This slightly complicates things when diagnostic JVM messages are used because these messages are printed directly to original stream descriptors by the JVM, bypassing System.out or System.err substitutions.

In those rare cases when the original JVM output streams are needed (possibly mixed with what the tests have printed), junit4 can be configured to leave the original streams on disk or pipe them to ANT's output. An example is shown below:

Should one need to preserve the original output files (in case they are large, for example), the configuration would then look as follows:

This would result in the following message being printed to ANT (note the output file name contains an execution-unique element to avoid clashing with other forked JVMs or builds).

[junit4:junit4] JVM J0: stdout was not empty, see: /home/[...]/junit4-J0-1058309761ea5fafd.sysout
[junit4:junit4] JVM J0: stderr was not empty, see: /home/[...]/junit4-J0-1058309761ea5fafd.syserr
randomizedtesting-release-2.1.6/junit4-ant/src/tasks/index.html000066400000000000000000000002541235451432000245760ustar00rootroot00000000000000 Follow to: junit4 documentation. randomizedtesting-release-2.1.6/junit4-ant/src/tasks/js/000077500000000000000000000000001235451432000232145ustar00rootroot00000000000000randomizedtesting-release-2.1.6/junit4-ant/src/tasks/js/google-code-prettify/000077500000000000000000000000001235451432000272445ustar00rootroot00000000000000randomizedtesting-release-2.1.6/junit4-ant/src/tasks/js/google-code-prettify/prettify.css000066400000000000000000000012431235451432000316240ustar00rootroot00000000000000.pln{color:#000}@media screen{.str{color:#080}.kwd{color:#008}.com{color:#800}.typ{color:#606}.lit{color:#066}.pun,.opn,.clo{color:#660}.tag{color:#008}.atn{color:#606}.atv{color:#080}.dec,.var{color:#606}.fun{color:red}}@media print,projection{.str{color:#060}.kwd{color:#006;font-weight:bold}.com{color:#600;font-style:italic}.typ{color:#404;font-weight:bold}.lit{color:#044}.pun,.opn,.clo{color:#440}.tag{color:#006;font-weight:bold}.atn{color:#404}.atv{color:#060}}pre.prettyprint{padding:2px;border:1px solid #888}ol.linenums{margin-top:0;margin-bottom:0}li.L0,li.L1,li.L2,li.L3,li.L5,li.L6,li.L7,li.L8{list-style-type:none}li.L1,li.L3,li.L5,li.L7,li.L9{background:#eee}randomizedtesting-release-2.1.6/junit4-ant/src/tasks/stylesheets/000077500000000000000000000000001235451432000251545ustar00rootroot00000000000000randomizedtesting-release-2.1.6/junit4-ant/src/tasks/stylesheets/antmanual.css000066400000000000000000000015471235451432000276550ustar00rootroot00000000000000/* * Licensed to the Apache Software Foundation (ASF) under one or more * contributor license agreements. See the NOTICE file distributed with * this work for additional information regarding copyright ownership. * The ASF licenses this file to You under the Apache License, Version 2.0 * (the "License"); you may not use this file except in compliance with * the License. You may obtain a copy of the License at * * http://www.apache.org/licenses/LICENSE-2.0 * * Unless required by applicable law or agreed to in writing, software * distributed under the License is distributed on an "AS IS" BASIS, * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. * See the License for the specific language governing permissions and * limitations under the License. * */ body { background-image:url(/images/beta.png) } randomizedtesting-release-2.1.6/junit4-ant/src/tasks/stylesheets/junit4.css000066400000000000000000000002201235451432000270750ustar00rootroot00000000000000 span.junit4 { background-color: #e0f0cc; } tr.junit4 td:first-child { background-color: #e0f0cc; } .junitcompat td { color: #a0a0a0; } randomizedtesting-release-2.1.6/junit4-ant/src/tasks/stylesheets/style.css000066400000000000000000000030521235451432000270260ustar00rootroot00000000000000/* * Licensed to the Apache Software Foundation (ASF) under one or more * contributor license agreements. See the NOTICE file distributed with * this work for additional information regarding copyright ownership. * The ASF licenses this file to You under the Apache License, Version 2.0 * (the "License"); you may not use this file except in compliance with * the License. You may obtain a copy of the License at * * http://www.apache.org/licenses/LICENSE-2.0 * * Unless required by applicable law or agreed to in writing, software * distributed under the License is distributed on an "AS IS" BASIS, * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. * See the License for the specific language governing permissions and * limitations under the License. * */ h2 { font-size: 200%; background-color: ffffff; } h3 { font-size: 130%; color: #ffffff; background-color: #525D76; } h4 { color: #ffffff; background-color: #828DA6; } td { background-color: eeeeee; color: 000000; } /* first row */ table tr:first-child td { background-color: cccccc; color: 000000; } /* or th as first row */ table th { background-color: cccccc; color: 000000; } pre { background-color: efefef; } /* code snippets in examples and tutorials */ .code { background: #EFEFEF; margin-top: } /* highlight console output */ .output { color: #FFFFFF; background: #837A67; } ul.inlinelist { list-style-type: none; margin-left: 0; padding: 0; } randomizedtesting-release-2.1.6/junit4-ant/src/test/000077500000000000000000000000001235451432000224325ustar00rootroot00000000000000randomizedtesting-release-2.1.6/junit4-ant/src/test/java/000077500000000000000000000000001235451432000233535ustar00rootroot00000000000000randomizedtesting-release-2.1.6/junit4-ant/src/test/java/com/000077500000000000000000000000001235451432000241315ustar00rootroot00000000000000randomizedtesting-release-2.1.6/junit4-ant/src/test/java/com/carrotsearch/000077500000000000000000000000001235451432000266115ustar00rootroot00000000000000randomizedtesting-release-2.1.6/junit4-ant/src/test/java/com/carrotsearch/ant/000077500000000000000000000000001235451432000273735ustar00rootroot00000000000000randomizedtesting-release-2.1.6/junit4-ant/src/test/java/com/carrotsearch/ant/tasks/000077500000000000000000000000001235451432000305205ustar00rootroot00000000000000randomizedtesting-release-2.1.6/junit4-ant/src/test/java/com/carrotsearch/ant/tasks/junit4/000077500000000000000000000000001235451432000317355ustar00rootroot00000000000000TestEventBusSanityCheck.java000066400000000000000000000054351235451432000372510ustar00rootroot00000000000000randomizedtesting-release-2.1.6/junit4-ant/src/test/java/com/carrotsearch/ant/tasks/junit4package com.carrotsearch.ant.tasks.junit4; import java.util.ArrayDeque; import java.util.Deque; import java.util.List; import java.util.concurrent.Callable; import java.util.concurrent.ExecutorService; import java.util.concurrent.Executors; import java.util.concurrent.Future; import java.util.concurrent.atomic.AtomicBoolean; import org.junit.Test; import com.carrotsearch.randomizedtesting.RandomizedTest; import com.carrotsearch.randomizedtesting.annotations.Repeat; import com.carrotsearch.randomizedtesting.annotations.ThreadLeakLingering; import com.carrotsearch.randomizedtesting.annotations.ThreadLeakScope; import com.carrotsearch.randomizedtesting.annotations.ThreadLeakScope.Scope; import com.google.common.collect.Lists; import com.google.common.eventbus.EventBus; import com.google.common.eventbus.Subscribe; @ThreadLeakScope(Scope.SUITE) @ThreadLeakLingering(linger = 1000) public class TestEventBusSanityCheck extends RandomizedTest { static class SlaveIdle { public void finished() { sleep(randomIntBetween(1, 50)); } public void newSuite(String suiteName) { sleep(randomIntBetween(1, 2)); } } @Test @Repeat(iterations = 100) public void testArrayQueueReentrance() throws Exception { // Mockups. final List foo = Lists.newArrayList(); for (int i = randomIntBetween(2, 1000); --i > 0;) { foo.add(randomAsciiOfLength(20)); } final EventBus aggregatedBus = new EventBus("aggregated"); final AtomicBoolean hadErrors = new AtomicBoolean(); // Code mirrors JUnit4's behavior. final Deque stealingQueue = new ArrayDeque(foo); aggregatedBus.register(new Object() { volatile Thread foo; @Subscribe public void onSlaveIdle(SlaveIdle slave) { final Thread other = foo; if (other != null) { hadErrors.set(true); throw new RuntimeException("Wtf? two threads in a handler: " + other + " and " + Thread.currentThread()); } foo = Thread.currentThread(); if (stealingQueue.isEmpty()) { slave.finished(); } else { String suiteName = stealingQueue.pop(); slave.newSuite(suiteName); } foo = null; } }); // stress. ExecutorService executor = Executors.newCachedThreadPool(); final List> slaves = Lists.newArrayList(); for (int i = 0; i < randomIntBetween(1, 10); i++) { slaves.add(new Callable() { @Override public Void call() throws Exception { aggregatedBus.post(new SlaveIdle()); return null; } }); } for (Future f : executor.invokeAll(slaves)) { f.get(); } executor.shutdown(); assertFalse(hadErrors.get()); } } TestJsonByteArrayRoundtrip.java000066400000000000000000000033631235451432000400310ustar00rootroot00000000000000randomizedtesting-release-2.1.6/junit4-ant/src/test/java/com/carrotsearch/ant/tasks/junit4package com.carrotsearch.ant.tasks.junit4; import java.io.ByteArrayInputStream; import java.io.ByteArrayOutputStream; import java.util.Arrays; import org.junit.Assert; import org.junit.Test; import com.carrotsearch.ant.tasks.junit4.events.AppendStdErrEvent; import com.carrotsearch.ant.tasks.junit4.events.Deserializer; import com.carrotsearch.ant.tasks.junit4.events.IEvent; import com.carrotsearch.ant.tasks.junit4.events.Serializer; import com.carrotsearch.randomizedtesting.RandomizedTest; import com.carrotsearch.randomizedtesting.annotations.Repeat; public class TestJsonByteArrayRoundtrip extends RandomizedTest { @Test @Repeat(iterations = 100) public void testRoundTrip() throws Exception { byte[] bytes = new byte[randomIntBetween(0, 1024)]; getRandom().nextBytes(bytes); check(bytes); } @Test public void testSimpleAscii() throws Exception { check("ABCabc0123".getBytes("UTF-8")); check("\n\t".getBytes("UTF-8")); } private void check(byte[] bytes) throws Exception { ByteArrayOutputStream baos = new ByteArrayOutputStream(); Serializer s = new Serializer(baos); s.serialize(new AppendStdErrEvent(bytes, 0, bytes.length)); s.flush(); s.close(); Deserializer deserializer = new Deserializer(new ByteArrayInputStream(baos.toByteArray()), Thread.currentThread().getContextClassLoader()); IEvent deserialize = deserializer.deserialize(); Assert.assertTrue(deserialize instanceof AppendStdErrEvent); AppendStdErrEvent e = ((AppendStdErrEvent) deserialize); baos.reset(); e.copyTo(baos); Assert.assertTrue( "Exp: " + Arrays.toString(bytes) + "\n" + "was: " + Arrays.toString(baos.toByteArray()), Arrays.equals(bytes, baos.toByteArray())); } } TestXmlStringsRoundtrip.java000066400000000000000000000044771235451432000374160ustar00rootroot00000000000000randomizedtesting-release-2.1.6/junit4-ant/src/test/java/com/carrotsearch/ant/tasks/junit4package com.carrotsearch.ant.tasks.junit4; import java.io.ByteArrayInputStream; import java.io.ByteArrayOutputStream; import java.util.Arrays; import java.util.Random; import javax.xml.parsers.DocumentBuilder; import javax.xml.parsers.DocumentBuilderFactory; import org.junit.Test; import org.simpleframework.xml.Attribute; import org.simpleframework.xml.Element; import org.simpleframework.xml.Root; import org.simpleframework.xml.core.Persister; import org.simpleframework.xml.transform.RegistryMatcher; import org.xml.sax.SAXParseException; import com.carrotsearch.ant.tasks.junit4.listeners.antxml.XmlStringTransformerAccess; import com.carrotsearch.randomizedtesting.RandomizedTest; import com.carrotsearch.randomizedtesting.annotations.Repeat; import com.google.common.base.Charsets; public class TestXmlStringsRoundtrip extends RandomizedTest { @Test @Repeat(iterations = 100) public void testRoundTrip() throws Exception { char[] chars = new char[randomIntBetween(0, 1024)]; Random random = getRandom(); for (int i = 0; i < chars.length; i++) { chars[i] = (char) random.nextInt(); } check(chars); } @Test public void testBoundary() throws Exception { check(new char [] {'a', 0x0000, 'z'}); check(new char [] {'a', 0x0001, 'z'}); } @Root public static class Model { @Attribute public String attribute; @Element(name = "system-out", data = true, required = true) public String contents = ""; public Model() {} public Model(String s) { attribute = contents = s; } } private void check(char[] chars) throws Exception { ByteArrayOutputStream baos = new ByteArrayOutputStream(); RegistryMatcher rm = new RegistryMatcher(); rm.bind(String.class, XmlStringTransformerAccess.getInstance()); Persister persister = new Persister(rm); persister.write(new Model(new String(chars)), baos); DocumentBuilderFactory docBuilderFactory = DocumentBuilderFactory.newInstance(); DocumentBuilder docBuilder = docBuilderFactory.newDocumentBuilder(); try { docBuilder.parse(new ByteArrayInputStream(baos.toByteArray())); } catch (SAXParseException e) { System.out.println("Input: " + Arrays.toString(chars)); System.out.println("XML: " + new String(baos.toByteArray(), Charsets.UTF_8)); throw e; } } } randomizedtesting-release-2.1.6/junit4-ant/src/test/java/com/carrotsearch/ant/tasks/junit4/it/000077500000000000000000000000001235451432000323515ustar00rootroot00000000000000AntBuildFileTestBase.java000066400000000000000000000110661235451432000370760ustar00rootroot00000000000000randomizedtesting-release-2.1.6/junit4-ant/src/test/java/com/carrotsearch/ant/tasks/junit4/itpackage com.carrotsearch.ant.tasks.junit4.it; import static org.junit.matchers.JUnitMatchers.containsString; import java.io.ByteArrayOutputStream; import java.io.File; import java.io.IOException; import java.io.PrintStream; import org.apache.tools.ant.BuildException; import org.apache.tools.ant.DefaultLogger; import org.apache.tools.ant.MagicNames; import org.apache.tools.ant.Project; import org.apache.tools.ant.ProjectHelper; import org.apache.tools.ant.launch.Launcher; import org.apache.tools.ant.taskdefs.Java; import org.apache.tools.ant.types.Path; import org.apache.tools.ant.util.LoaderUtils; import org.junit.After; import org.junit.Assert; /** * An equivalent of BuildFileTest for JUnit4. */ public class AntBuildFileTestBase { private Project project; private ByteArrayOutputStream output; private DefaultLogger listener; protected PrintStream restoreSysout; protected PrintStream restoreSyserr; protected void setupProject(File projectFile) { try { restoreSysout = System.out; restoreSyserr = System.err; output = new ByteArrayOutputStream(); PrintStream ps = new PrintStream(output, true, "UTF-8"); System.setOut(ps); System.setErr(ps); project = new Project(); project.init(); project.setUserProperty(MagicNames.ANT_FILE, projectFile.getAbsolutePath()); ProjectHelper.configureProject(project, projectFile); listener = new DefaultLogger(); listener.setMessageOutputLevel(Project.MSG_DEBUG); listener.setErrorPrintStream(ps); listener.setOutputPrintStream(ps); getProject().addBuildListener(listener); DefaultLogger console = new DefaultLogger(); console.setMessageOutputLevel(Project.MSG_INFO); console.setErrorPrintStream(restoreSyserr); console.setOutputPrintStream(restoreSysout); getProject().addBuildListener(console); } catch (IOException e) { throw new RuntimeException(e); } } @After public void restoreSysouts() { if (restoreSysout != null) System.setOut(restoreSysout); if (restoreSyserr != null) System.setErr(restoreSyserr); } protected final Project getProject() { if (project == null) { throw new IllegalStateException( "Setup project file with setupProject(File) first."); } return project; } protected final void assertLogContains(String substring) { Assert.assertTrue("Log did not contain: '" + substring + "'", getLog() .contains(substring)); } protected final void assertLogDoesNotContain(String substring) { Assert.assertTrue("Log contained: '" + substring + "'", !getLog().contains(substring)); } protected final String getLog() { try { return new String(output.toByteArray(), "UTF-8"); } catch (Exception e) { throw new RuntimeException(e); } } protected final void expectBuildExceptionContaining(String target, String message) { try { executeTarget(target); Assert.fail("Expected a build failure with message: " + message); } catch (BuildException e) { Assert.assertThat(e.getMessage(), containsString(message)); } } protected final void executeTarget(String target) { getProject().executeTarget(target); } protected final void executeForkedTarget(String target) { executeForkedTarget(target, 10 * 1000L); } protected final void executeForkedTarget(String target, long timeout) { Path antPath = new Path(getProject()); antPath.createPathElement().setLocation(sourceOf(Project.class)); antPath.createPathElement().setLocation(sourceOf(Launcher.class)); Java java = new Java(); java.setTaskName("forked"); java.setProject(getProject()); java.setClassname("org.apache.tools.ant.launch.Launcher"); java.createClasspath().add(antPath); java.setFork(true); java.setSpawn(false); java.setTimeout(timeout); java.setFailonerror(false); java.setOutputproperty("stdout"); java.setErrorProperty("stderr"); java.createArg().setValue("-f"); java.createArg().setValue(getProject().getUserProperty(MagicNames.ANT_FILE)); java.createArg().setValue(target); java.execute(); getProject().log("Forked stdout:\n" + getProject().getProperty("stdout")); getProject().log("Forked stderr:\n" + getProject().getProperty("stderr")); } /** * Get the source location of a given class. */ private static File sourceOf(Class clazz) { return LoaderUtils.getResourceSource( clazz.getClassLoader(), clazz.getName().replace('.', '/') + ".class"); } } JUnit4XmlTestBase.java000066400000000000000000000024471235451432000363750ustar00rootroot00000000000000randomizedtesting-release-2.1.6/junit4-ant/src/test/java/com/carrotsearch/ant/tasks/junit4/itpackage com.carrotsearch.ant.tasks.junit4.it; import java.io.File; import java.net.URL; import org.junit.Before; import org.junit.Rule; import org.junit.rules.TestRule; import org.junit.runner.Description; import org.junit.runners.model.Statement; /** * A base class for tests contained in junit4.xml * file. */ public class JUnit4XmlTestBase extends AntBuildFileTestBase { @Rule public TestRule dumpLogOnError = new TestRule() { @Override public Statement apply(final Statement base, Description description) { return new Statement() { @Override public void evaluate() throws Throwable { try { base.evaluate(); } catch (Throwable e) { System.out.println("Ant log: " + getLog()); throw e; } } }; } }; @Before public void setUp() throws Exception { URL resource = getClass().getClassLoader().getResource("junit4.xml"); super.setupProject(new File(resource.getFile())); } protected static int countPattern(String output, String substr) { int count = 0; for (int i = 0; i < output.length();) { int index = output.indexOf(substr, i); if (index < 0) { break; } count++; i = index + 1; } return count; } } TestAltJavaVendors.java000066400000000000000000000015621235451432000366640ustar00rootroot00000000000000randomizedtesting-release-2.1.6/junit4-ant/src/test/java/com/carrotsearch/ant/tasks/junit4/itpackage com.carrotsearch.ant.tasks.junit4.it; import java.io.File; import org.apache.tools.ant.types.Path; import org.junit.Assert; import org.junit.Assume; import org.junit.Test; public class TestAltJavaVendors extends JUnit4XmlTestBase { @Test public void altVendors() { String altVendors = System.getProperty("alt.jvms"); Assume.assumeTrue(altVendors != null && !altVendors.trim().isEmpty()); for (String jvm : new Path(getProject(), altVendors).list()) { getProject().log("Trying JVM: " + jvm); Assert.assertTrue("JVM is not a file: " + jvm, new File(jvm).isFile()); Assert.assertTrue("JVM is not executable: " + jvm, new File(jvm).canExecute()); getProject().setProperty("jvm.exec", jvm); expectBuildExceptionContaining("alt-vendor", "1 suite, 5 tests, 1 error, 1 failure, 2 ignored (1 assumption)"); } } } TestAntXmlReport.java000066400000000000000000000024001235451432000363700ustar00rootroot00000000000000randomizedtesting-release-2.1.6/junit4-ant/src/test/java/com/carrotsearch/ant/tasks/junit4/itpackage com.carrotsearch.ant.tasks.junit4.it; import java.io.File; import javax.xml.parsers.DocumentBuilder; import javax.xml.parsers.DocumentBuilderFactory; import org.junit.Assert; import org.junit.Test; public class TestAntXmlReport extends JUnit4XmlTestBase { @Test public void antxml() throws Exception { super.executeTarget("antxml"); // Simple check for existence. Assert.assertTrue( new File(getProject().getBaseDir(), "ant-xmls/TEST-com.carrotsearch.ant.tasks.junit4.tests.TestBeforeClassError.xml").length() > 0); Assert.assertTrue( new File(getProject().getBaseDir(), "ant-xmls/TEST-com.carrotsearch.ant.tasks.junit4.tests.replication.TestSuiteReplicated-2.xml").length() > 0); // Check for warning messages about duplicate suites. assertLogContains("Duplicate suite name used with XML reports"); // Attempt to read and parse. File basedir = new File(getProject().getBaseDir(), "ant-xmls"); for (File f : basedir.listFiles()) { if (f.isFile() && f.getName().endsWith(".xml")) { DocumentBuilderFactory docBuilderFactory = DocumentBuilderFactory.newInstance(); DocumentBuilder docBuilder = docBuilderFactory.newDocumentBuilder(); docBuilder.parse(f); } } } } TestChildVmSysprops.java000066400000000000000000000003261235451432000371070ustar00rootroot00000000000000randomizedtesting-release-2.1.6/junit4-ant/src/test/java/com/carrotsearch/ant/tasks/junit4/itpackage com.carrotsearch.ant.tasks.junit4.it; import org.junit.Test; public class TestChildVmSysprops extends JUnit4XmlTestBase { @Test public void sysprops() { executeTarget("childvm_sysprops"); } } TestCrashesAndExceptions.java000066400000000000000000000015321235451432000400530ustar00rootroot00000000000000randomizedtesting-release-2.1.6/junit4-ant/src/test/java/com/carrotsearch/ant/tasks/junit4/itpackage com.carrotsearch.ant.tasks.junit4.it; import java.io.File; import org.junit.Test; public class TestCrashesAndExceptions extends JUnit4XmlTestBase { @Test public void slavehanging() { executeTarget("slavehanging"); assertLogContains("Caused by: java.lang.ArithmeticException"); } @Test public void jvmcrash() { expectBuildExceptionContaining("jvmcrash", "was not empty, see:"); File cwd = getProject().getBaseDir(); for (File crashDump : cwd.listFiles()) { if (crashDump.isFile() && (crashDump.getName().matches("^hs_err_pid.+\\.log") || crashDump.getName().endsWith(".mdmp") || crashDump.getName().endsWith(".dmp") || crashDump.getName().endsWith(".dump") || crashDump.getName().endsWith(".trc"))) { crashDump.delete(); } } } } TestCwdConflict.java000066400000000000000000000003271235451432000361760ustar00rootroot00000000000000randomizedtesting-release-2.1.6/junit4-ant/src/test/java/com/carrotsearch/ant/tasks/junit4/itpackage com.carrotsearch.ant.tasks.junit4.it; import org.junit.Test; public class TestCwdConflict extends JUnit4XmlTestBase { @Test public void cwdconflict() { super.executeTarget("cwdconflict"); } } TestDuplicateResourceCollections.java000066400000000000000000000005671235451432000416260ustar00rootroot00000000000000randomizedtesting-release-2.1.6/junit4-ant/src/test/java/com/carrotsearch/ant/tasks/junit4/itpackage com.carrotsearch.ant.tasks.junit4.it; import org.junit.Test; public class TestDuplicateResourceCollections extends JUnit4XmlTestBase { @Test public void duplicateResourceCollectionEntries() { super.executeTarget("duplicateresources"); assertLogContains("10 suites, 10 tests"); assertLogContains("JVM J0"); assertLogContains("JVM J1"); } } TestFileEncodings.java000066400000000000000000000022651235451432000365130ustar00rootroot00000000000000randomizedtesting-release-2.1.6/junit4-ant/src/test/java/com/carrotsearch/ant/tasks/junit4/itpackage com.carrotsearch.ant.tasks.junit4.it; import java.io.DataInputStream; import java.io.File; import java.io.FileInputStream; import java.io.IOException; import org.junit.Assert; import org.junit.Test; public class TestFileEncodings extends JUnit4XmlTestBase { @Test public void checkTypicalEncodings() throws IOException { super.executeTarget("fileencodings"); File logFile = new File(getProject().getProperty("log.file")); byte [] contents = new byte [(int) logFile.length()]; DataInputStream dis = new DataInputStream(new FileInputStream(logFile)); dis.readFully(contents); dis.close(); String log = new String(contents, "UTF-8"); Assert.assertEquals(1, countPattern(log, "US-ASCII=cze??, ??????, ???")); Assert.assertEquals(1, countPattern(log, "iso8859-1=cze??, ??????, ???")); Assert.assertEquals(1, countPattern(log, "UTF-8=cześć, Привет, 今日ã¯")); Assert.assertEquals(1, countPattern(log, "UTF-16=cześć, Привет, 今日ã¯")); Assert.assertEquals(1, countPattern(log, "UTF-16LE=cześć, Привет, 今日ã¯")); Assert.assertEquals(1, countPattern(log, "UTF-32=cześć, Привет, 今日ã¯")); } } TestFiltering.java000066400000000000000000000014601235451432000357210ustar00rootroot00000000000000randomizedtesting-release-2.1.6/junit4-ant/src/test/java/com/carrotsearch/ant/tasks/junit4/itpackage com.carrotsearch.ant.tasks.junit4.it; import org.junit.Test; public class TestFiltering extends JUnit4XmlTestBase { @Test public void classfilter() { executeTarget("classfilter"); assertLogContains("Tests summary: 1 suite"); } @Test public void methodfilter() { executeTarget("methodfilter"); assertLogContains("Tests summary: 1 suite, 2 tests"); } @Test public void filterexpression() { executeTarget("filterexpression"); assertLogContains("Parsed test filtering expression: (@foo AND (NOT @bar))"); assertLogContains(">foo<"); assertLogDoesNotContain(">foobar<"); assertLogDoesNotContain(">bar<"); assertLogDoesNotContain(">foobar2<"); assertLogDoesNotContain(">bar2<"); assertLogContains("Tests summary: 2 suites, 1 test"); } } TestHeartbeat.java000066400000000000000000000005431235451432000356760ustar00rootroot00000000000000randomizedtesting-release-2.1.6/junit4-ant/src/test/java/com/carrotsearch/ant/tasks/junit4/itpackage com.carrotsearch.ant.tasks.junit4.it; import org.junit.Test; /** * Test heartbeat on slow, non-updating tests. */ public class TestHeartbeat extends JUnit4XmlTestBase { @Test public void testHeartbeat() { executeTarget("testHeartbeat"); assertLogContains("HEARTBEAT J0"); assertLogContains("at: HeartbeatSlow.method1"); } } TestIfNoTestsOption.java000066400000000000000000000017321235451432000370470ustar00rootroot00000000000000randomizedtesting-release-2.1.6/junit4-ant/src/test/java/com/carrotsearch/ant/tasks/junit4/itpackage com.carrotsearch.ant.tasks.junit4.it; import org.junit.Test; public class TestIfNoTestsOption extends JUnit4XmlTestBase { @Test public void allFilteredOut() { expectBuildExceptionContaining("allFilteredOut", "There were no executed tests: 0 suites, 0 tests"); } @Test public void oneIgnored() { expectBuildExceptionContaining("oneIgnored", "There were no executed tests: 1 suite, 1 test, 1 ignored"); } @Test public void oneAssumptionIgnored() { expectBuildExceptionContaining("oneAssumptionIgnored", "There were no executed tests: 1 suite, 1 test, 1 ignored"); } @Test public void oneSuccessfull() { executeTarget("oneSuccessful"); } @Test public void oneFailure() { expectBuildExceptionContaining("oneFailure", "There were test failures: 1 suite, 1 test, 1 failure"); } @Test public void oneError() { expectBuildExceptionContaining("oneError", "There were test failures: 1 suite, 1 test, 1 error"); } } TestJUnitCompat.java000066400000000000000000000011271235451432000361730ustar00rootroot00000000000000randomizedtesting-release-2.1.6/junit4-ant/src/test/java/com/carrotsearch/ant/tasks/junit4/itpackage com.carrotsearch.ant.tasks.junit4.it; import org.junit.Test; public class TestJUnitCompat extends JUnit4XmlTestBase { @Test public void junitcompat1() { super.expectBuildExceptionContaining( "junitcompat1", " elements are not supported"); } @Test public void junitcompat2() { super.expectBuildExceptionContaining( "junitcompat2", " elements are not supported"); } @Test public void junitcompat3() { super.expectBuildExceptionContaining( "junitcompat3", " elements are not supported"); } } TestJsonReport.java000066400000000000000000000011301235451432000360750ustar00rootroot00000000000000randomizedtesting-release-2.1.6/junit4-ant/src/test/java/com/carrotsearch/ant/tasks/junit4/itpackage com.carrotsearch.ant.tasks.junit4.it; import java.io.File; import org.junit.Assert; import org.junit.Test; public class TestJsonReport extends JUnit4XmlTestBase { @Test public void antxml() { super.executeTarget("json"); Assert.assertTrue( new File(getProject().getBaseDir(), "json/report.json").length() > 0); Assert.assertTrue( new File(getProject().getBaseDir(), "json/report.jsonp").length() > 0); Assert.assertTrue( new File(getProject().getBaseDir(), "json/output.html").length() > 0); } } TestJvmLogging.java000066400000000000000000000010101235451432000360300ustar00rootroot00000000000000randomizedtesting-release-2.1.6/junit4-ant/src/test/java/com/carrotsearch/ant/tasks/junit4/itpackage com.carrotsearch.ant.tasks.junit4.it; import org.junit.Test; /** * Check JVM logging settings. Thet seem to use process descriptors not * {@link System} streams. */ public class TestJvmLogging extends JUnit4XmlTestBase { @Test public void jvmverbose() { executeTarget("jvmverbose"); assertLogContains("was not empty, see"); } @Test public void sysouts() { executeTarget("sysouts"); assertLogContains("syserr-syserr-contd."); assertLogContains("sysout-sysout-contd."); } } TestMiscJUnit4Attributes.java000066400000000000000000000056431235451432000400050ustar00rootroot00000000000000randomizedtesting-release-2.1.6/junit4-ant/src/test/java/com/carrotsearch/ant/tasks/junit4/itpackage com.carrotsearch.ant.tasks.junit4.it; import org.junit.Test; import com.carrotsearch.ant.tasks.junit4.tests.TestAfterClassError; import com.carrotsearch.ant.tasks.junit4.tests.TestBeforeClassError; public class TestMiscJUnit4Attributes extends JUnit4XmlTestBase { @Test public void customprefix() { executeForkedTarget("customprefix"); } @Test public void statuses() throws Throwable { expectBuildExceptionContaining("statuses", "1 suite, 5 tests, 1 error, 1 failure, 2 ignored (1 assumption)"); } @Test public void ignoredSuite() throws Throwable { executeTarget("ignoredSuite"); assertLogContains("Tests summary: 1 suite, 0 tests"); } @Test public void beforeClassError() throws Throwable { expectBuildExceptionContaining("beforeClassError", "1 suite, 0 tests, 1 suite-level error"); assertLogContains("| " + TestBeforeClassError.class.getSimpleName() + " (suite)"); } @Test public void afterClassError() throws Throwable { expectBuildExceptionContaining("afterClassError", "1 suite, 1 test, 1 suite-level error"); assertLogContains("| " + TestAfterClassError.class.getSimpleName() + " (suite)"); } @Test public void hierarchicalSuiteDescription() throws Throwable { expectBuildExceptionContaining("hierarchicalSuiteDescription", "1 suite, 2 tests, 3 suite-level errors, 1 error"); } @Test public void dir() { executeTarget("dir"); } @Test public void maxmem() { executeTarget("maxmem"); } @Test public void jvmarg() { executeTarget("jvmarg"); } @Test public void seedpassing() { executeTarget("seedpassing"); } @Test public void seedpassingInvalid() { expectBuildExceptionContaining("seedpassing.invalid", "Not a valid seed chain"); } @Test public void reproducestring() { executeTarget("reproducestring"); assertLogContains("2> Reproduce: "); } @Test public void assertions() { expectBuildExceptionContaining("assertions", "There were test failures"); assertLogContains("> Throwable #1: java.lang.AssertionError: foobar"); } @Test public void balancing() { executeTarget("balancing"); assertLogContains("Assignment hint: J0 (cost 2019) com.carrotsearch.ant.tasks.junit4.tests.sub2.TestTwoSeconds (by ExecutionTimeBalancer)"); assertLogContains("Assignment hint: J1 (cost 1002) com.carrotsearch.ant.tasks.junit4.tests.sub2.TestOneSecond (by ExecutionTimeBalancer)"); assertLogContains("Assignment hint: J1 (cost 501) com.carrotsearch.ant.tasks.junit4.tests.sub2.TestHalfSecond (by ExecutionTimeBalancer)"); assertLogContains("Assignment hint: J1 (cost 2) com.carrotsearch.ant.tasks.junit4.tests.sub2.TestZeroSeconds (by ExecutionTimeBalancer)"); } @Test public void balancing_nohints() { executeTarget("balancing_nohints"); } @Test public void mergehints() { executeTarget("mergehints"); } } TestOomCode.java000066400000000000000000000006031235451432000353210ustar00rootroot00000000000000randomizedtesting-release-2.1.6/junit4-ant/src/test/java/com/carrotsearch/ant/tasks/junit4/itpackage com.carrotsearch.ant.tasks.junit4.it; import org.junit.Ignore; import org.junit.Test; public class TestOomCode extends JUnit4XmlTestBase { @Test @Ignore("Not portable across JVMs") public void oom() { super.executeForkedTarget("oomcode", 5 * 60 * 1000L); assertLogContains("Forked JVM ran out of memory"); assertLogContains("WARN: JVM out of memory"); } } TestOomPermGen.java000066400000000000000000000006271235451432000360120ustar00rootroot00000000000000randomizedtesting-release-2.1.6/junit4-ant/src/test/java/com/carrotsearch/ant/tasks/junit4/itpackage com.carrotsearch.ant.tasks.junit4.it; import org.junit.Ignore; import org.junit.Test; public class TestOomPermGen extends JUnit4XmlTestBase { @Test @Ignore("Not portable across JVMs") public void oom() { super.executeForkedTarget("oompermgen", 5 * 60 * 1000L); if (!getLog().contains("1 ignored (1 assumption)")) { assertLogContains("java.lang.OutOfMemoryError"); } } } TestOutputCapture.java000066400000000000000000000013201235451432000366150ustar00rootroot00000000000000randomizedtesting-release-2.1.6/junit4-ant/src/test/java/com/carrotsearch/ant/tasks/junit4/itpackage com.carrotsearch.ant.tasks.junit4.it; import org.junit.Test; /** * Test things related to output capturing. */ public class TestOutputCapture extends JUnit4XmlTestBase { @Test public void sysstreams() { executeTarget("sysstreams"); assertLogContains("Tests summary: 1 suite, 2 tests"); assertLogContains("1> sysout-sysout-contd."); assertLogContains("2> syserr-syserr-contd."); } @Test public void outofordersysouts() { executeTarget("outofordersysouts"); } @Test public void staticScopeOutput() { executeTarget("staticScopeOutput"); assertLogContains("1> static-scope"); assertLogContains("1> before-class"); assertLogContains("1> after-class"); } } TestPickSeed.java000066400000000000000000000024211235451432000354630ustar00rootroot00000000000000randomizedtesting-release-2.1.6/junit4-ant/src/test/java/com/carrotsearch/ant/tasks/junit4/itpackage com.carrotsearch.ant.tasks.junit4.it; import java.util.HashMap; import java.util.TreeSet; import java.util.regex.Matcher; import java.util.regex.Pattern; import org.junit.Assert; import org.junit.Test; public class TestPickSeed extends JUnit4XmlTestBase { @Test public void pickSeed() { for (int i = 0; i < 7; i++) { super.executeTarget("randomsysproperty"); } HashMap> props = new HashMap>(); for (String key : new String [] { "prefix.dummy1", "prefix.dummy2", "replaced.dummy1", "replaced.dummy2", }) { TreeSet values = new TreeSet(); Pattern p = Pattern.compile("(?:> )(" + key + ")(?:=)([^\\s]+)"); Matcher m = p.matcher(getLog()); while (m.find()) { values.add(m.group(2)); } props.put(key, values); } Assert.assertEquals(props.get("prefix.dummy1"), props.get("replaced.dummy1")); Assert.assertEquals(props.get("prefix.dummy2"), props.get("replaced.dummy2")); // At least two unique values. Assert.assertTrue(props.get("prefix.dummy1").size() >= 2); // null (missing value) should be there. Assert.assertTrue(props.get("prefix.dummy2").contains("null")); } } TestPreconditions.java000066400000000000000000000014141235451432000366150ustar00rootroot00000000000000randomizedtesting-release-2.1.6/junit4-ant/src/test/java/com/carrotsearch/ant/tasks/junit4/itpackage com.carrotsearch.ant.tasks.junit4.it; import org.junit.Test; public class TestPreconditions extends JUnit4XmlTestBase { @Test public void nojunit() { expectBuildExceptionContaining("nojunit", "Forked JVM's classpath must include a junit4 JAR"); } @Test public void oldjunit() { executeForkedTarget("oldjunit"); assertLogContains("Forked JVM's classpath must use JUnit 4.10 or newer"); } @Test public void nojunit_task() { executeForkedTarget("nojunit-task"); assertLogContains("JUnit JAR must be added to junit4 taskdef's classpath"); } @Test public void oldjunit_task() { executeForkedTarget("oldjunit-task"); assertLogContains("At least JUnit version 4.10 is required on junit4's taskdef classpath"); } } TestReplication.java000066400000000000000000000027741235451432000362600ustar00rootroot00000000000000randomizedtesting-release-2.1.6/junit4-ant/src/test/java/com/carrotsearch/ant/tasks/junit4/itpackage com.carrotsearch.ant.tasks.junit4.it; import java.util.Arrays; import java.util.HashSet; import java.util.regex.Matcher; import java.util.regex.Pattern; import org.junit.Assert; import org.junit.Test; public class TestReplication extends JUnit4XmlTestBase { @Test public void singleSuiteReplication() { super.executeTarget("replicateSingleTest"); assertLogContains("Replicated test, VM: 0"); assertLogContains("Replicated test, VM: 1"); assertLogContains("Replicated test, VM: 2"); } @Test public void replicationAndBalancing() { super.executeTarget("replicationAndBalancing"); assertLogContains("Non-replicated test, VM: 0"); assertLogContains("Non-replicated test, VM: 1"); assertLogContains("Replicated test, VM: 0"); assertLogContains("Replicated test, VM: 1"); assertLogContains("Replicated test, VM: 2"); } @Test public void pseudoBalancing() { super.executeTarget("pseudoBalancing"); assertLogContains("3 suites, 300 tests, 200 ignored (200 assumptions)"); String log = getLog(); for (int i = 0; i < 100; i++) { Pattern p = Pattern.compile("(Test " + i + " executed on VM )([0-9]+)"); Matcher m = p.matcher(log); Assert.assertTrue(m.find()); int jvm = Integer.parseInt(m.group(2)); HashSet s = new HashSet(Arrays.asList(0, 1, 2)); s.remove(jvm); for (int ignoredOnJvm : s) { assertLogContains("Test " + i + " ignored on VM " + ignoredOnJvm); } } } } TestShutdownHookDeadlock.java000066400000000000000000000010061235451432000400550ustar00rootroot00000000000000randomizedtesting-release-2.1.6/junit4-ant/src/test/java/com/carrotsearch/ant/tasks/junit4/itpackage com.carrotsearch.ant.tasks.junit4.it; import org.junit.Assert; import org.junit.Test; public class TestShutdownHookDeadlock extends JUnit4XmlTestBase { @Test public void slavehanging() { long start = System.currentTimeMillis(); executeForkedTarget("shutdownhook", 120 * 1000L); long end = System.currentTimeMillis(); // This isn't a strong assertion but it'll do here. If the execution time > 60 seconds // something is stinky. Assert.assertTrue(end - start < 60 * 1000); } } TestSourceSuitesAsInput.java000066400000000000000000000004311235451432000377340ustar00rootroot00000000000000randomizedtesting-release-2.1.6/junit4-ant/src/test/java/com/carrotsearch/ant/tasks/junit4/itpackage com.carrotsearch.ant.tasks.junit4.it; import org.junit.Test; public class TestSourceSuitesAsInput extends JUnit4XmlTestBase { @Test public void sourcesuites() { super.executeTarget("sourcesuites"); assertLogContains("Tests summary: 1 suite, 1 test"); } } TestStackOverflowInEventEmitter.java000066400000000000000000000004601235451432000414110ustar00rootroot00000000000000randomizedtesting-release-2.1.6/junit4-ant/src/test/java/com/carrotsearch/ant/tasks/junit4/itpackage com.carrotsearch.ant.tasks.junit4.it; import org.junit.Test; public class TestStackOverflowInEventEmitter extends JUnit4XmlTestBase { @Test public void stackoverflow() { super.expectBuildExceptionContaining("stackoverflow", "Quit event not received from the forked process?"); } } TestStatsProperties.java000066400000000000000000000003411235451432000371460ustar00rootroot00000000000000randomizedtesting-release-2.1.6/junit4-ant/src/test/java/com/carrotsearch/ant/tasks/junit4/itpackage com.carrotsearch.ant.tasks.junit4.it; import org.junit.Test; public class TestStatsProperties extends JUnit4XmlTestBase { @Test public void allFilteredOut() { super.executeTarget("statsProperties"); } } TestSuiteClassesBad.java000066400000000000000000000006671235451432000370240ustar00rootroot00000000000000randomizedtesting-release-2.1.6/junit4-ant/src/test/java/com/carrotsearch/ant/tasks/junit4/itpackage com.carrotsearch.ant.tasks.junit4.it; import org.junit.Test; public class TestSuiteClassesBad extends JUnit4XmlTestBase { @Test public void notaclass() { expectBuildExceptionContaining("notaclass", "File does not start with a class magic"); } @Test public void notinstantiable() { expectBuildExceptionContaining("notinstantiable", "There were test failures: 1 suite, 1 test, 1 error"); } } TestSuiteDuplicates.java000066400000000000000000000005251235451432000371060ustar00rootroot00000000000000randomizedtesting-release-2.1.6/junit4-ant/src/test/java/com/carrotsearch/ant/tasks/junit4/itpackage com.carrotsearch.ant.tasks.junit4.it; import org.junit.Test; public class TestSuiteDuplicates extends JUnit4XmlTestBase { @Test public void suiteduplicate() { super.executeTarget("suiteduplicate"); assertLogContains("2 suites, 2 tests"); assertLogContains("JVM J0"); assertLogContains("JVM J1"); } } TestSysProperties.java000066400000000000000000000021761235451432000366360ustar00rootroot00000000000000randomizedtesting-release-2.1.6/junit4-ant/src/test/java/com/carrotsearch/ant/tasks/junit4/itpackage com.carrotsearch.ant.tasks.junit4.it; import java.util.regex.Matcher; import java.util.regex.Pattern; import org.junit.Assert; import org.junit.Test; public class TestSysProperties extends JUnit4XmlTestBase { @Test public void failureProperty() { executeTarget("failureProperty"); } @Test public void failureTypePassing() { executeTarget("failureTypePassing"); assertLogContains("Throwable #1: com.carrotsearch.ant.tasks.junit4.tests.SyntheticException"); assertLogContains("Tests summary: 1 suite, 1 test, 1 error"); super.restoreSyserr.println(getLog()); } @Test public void escaping() { executeTarget("escaping"); assertLogContains("\"-Dsysprop.key2=abc def\""); } @Test public void sysproperty() { executeTarget("sysproperty"); } @Test public void env() { executeTarget("env"); } @Test public void iters() { executeTarget("iters"); Pattern p = Pattern.compile("TestSuccess\\.alwaysPasses"); Matcher matcher = p.matcher(getLog()); int count = 0; while (matcher.find()) { count++; } Assert.assertEquals(5, count); } } TestSysPropertySet.java000066400000000000000000000006211235451432000367730ustar00rootroot00000000000000randomizedtesting-release-2.1.6/junit4-ant/src/test/java/com/carrotsearch/ant/tasks/junit4/itpackage com.carrotsearch.ant.tasks.junit4.it; import org.junit.Test; public class TestSysPropertySet extends JUnit4XmlTestBase { @Test public void altVendors() { getProject().setProperty("prefix.dummy1", "value1"); getProject().setProperty("prefix.dummy2", "value2"); executeTarget("syspropertyset"); assertLogContains("value1"); assertLogContains("value2"); } } TestSysoutOOM.java000066400000000000000000000003211235451432000356520ustar00rootroot00000000000000randomizedtesting-release-2.1.6/junit4-ant/src/test/java/com/carrotsearch/ant/tasks/junit4/itpackage com.carrotsearch.ant.tasks.junit4.it; import org.junit.Test; public class TestSysoutOOM extends JUnit4XmlTestBase { @Test public void sysoutoom() { super.executeTarget("sysoutoom"); } } TestTextReport.java000066400000000000000000000062341235451432000361220ustar00rootroot00000000000000randomizedtesting-release-2.1.6/junit4-ant/src/test/java/com/carrotsearch/ant/tasks/junit4/itpackage com.carrotsearch.ant.tasks.junit4.it; import java.util.regex.Pattern; import org.junit.Assert; import org.junit.Test; import com.carrotsearch.ant.tasks.junit4.tests.FailInAfterClass; import com.carrotsearch.ant.tasks.junit4.tests.ReasonForAssumptionIgnored; /** * Test report-text listener. */ public class TestTextReport extends JUnit4XmlTestBase { @Test public void suiteerror() { super.executeTarget("suiteerror"); int count = countPattern(getLog(), FailInAfterClass.MESSAGE); Assert.assertEquals(1, count); } @Test public void reasonForIgnored() { super.executeTarget("reasonForIgnored"); assertLogContains("@DisabledGroup"); assertLogContains("> Cause: Annotated @Ignore"); assertLogContains("(Ignored method.)"); } @Test public void reasonForIgnoredByDisabledGroup() { super.executeTarget("reasonForIgnoredByDisabledGroup"); assertLogContains("(@DisabledGroup(value=foo bar))"); } @Test public void reasonForSuiteAssumptionIgnored() { super.executeTarget("reasonForSuiteAssumptionIgnored"); int count = countPattern(getLog(), ReasonForAssumptionIgnored.MESSAGE); Assert.assertEquals(2, count); } @Test public void listeners() { super.executeTarget("listeners"); assertLogContains("testStarted: passing(com.carrotsearch.ant.tasks.junit4.tests.SuiteListeners)"); assertLogContains("testFinished: passing(com.carrotsearch.ant.tasks.junit4.tests.SuiteListeners)"); } @Test public void timestamps() { super.executeTarget("timestamps"); Assert.assertTrue(getLog(), Pattern.compile("\\[([0-9]{2}):([0-9]{2}):([0-9]{2})\\.([0-9]{3})\\]").matcher(getLog()).find()); } @Test public void sysoutsOnSuiteFailure() { super.executeTarget("sysoutsOnSuiteFailure"); assertLogContains("ignored-sysout"); assertLogContains("success-sysout"); assertLogContains("afterclass-sysout"); assertLogContains("beforeclass-sysout"); super.restoreSyserr.println(getLog()); } @Test public void sysoutsOnSuiteTimeout() { super.executeTarget("sysoutsOnSuiteTimeout"); assertLogContains("beforeclass-sysout"); assertLogContains("test-sysout"); String log = getLog(); Assert.assertTrue( log.indexOf("1> test-sysout") < log.indexOf("Suite execution timed out:")); } @Test public void sysoutsPassthrough() { super.executeTarget("sysouts_passthrough"); } @Test public void failureslist() { super.executeTarget("failureslist"); assertLogContains("Tests with failures"); } @Test public void filtertrace_default() { super.executeTarget("filtertrace_default"); assertLogDoesNotContain("at sun.reflect."); assertLogDoesNotContain("at java.lang.reflect.Method"); assertLogDoesNotContain("at org.junit.runners."); assertLogDoesNotContain("at com.carrotsearch.ant.tasks.junit4.slave.SlaveMain"); } @Test public void filtertrace_custom() { super.executeTarget("filtertrace_custom"); assertLogContains("at sun.reflect."); assertLogContains("at java.lang.reflect.Method"); assertLogDoesNotContain("at org.junit."); assertLogDoesNotContain(".SlaveMain."); } } TestUnhandledSlaveFailure.java000066400000000000000000000007411235451432000402040ustar00rootroot00000000000000randomizedtesting-release-2.1.6/junit4-ant/src/test/java/com/carrotsearch/ant/tasks/junit4/itpackage com.carrotsearch.ant.tasks.junit4.it; import java.io.IOException; import org.junit.Test; import com.carrotsearch.ant.tasks.junit4.tests.FireUnhandledRunnerException; public class TestUnhandledSlaveFailure extends JUnit4XmlTestBase { @Test public void checkSlaveMainFailure() throws IOException { super.expectBuildExceptionContaining("slavemainfailure", "process threw an exception"); assertLogContains(FireUnhandledRunnerException.EXCEPTION_MESSAGE); } } TestWeirdClasses.java000066400000000000000000000005731235451432000363720ustar00rootroot00000000000000randomizedtesting-release-2.1.6/junit4-ant/src/test/java/com/carrotsearch/ant/tasks/junit4/itpackage com.carrotsearch.ant.tasks.junit4.it; import org.junit.Test; public class TestWeirdClasses extends JUnit4XmlTestBase { /* * Just run an example that shows JUnit's behavior on package-private/ abstract classes. * https://github.com/carrotsearch/randomizedtesting/issues/91 */ @Test public void antxml() { super.executeTarget("weirdclasses"); } } 000077500000000000000000000000001235451432000336665ustar00rootroot00000000000000randomizedtesting-release-2.1.6/junit4-ant/src/test/java/com/carrotsearch/ant/tasks/junit4/listeners000077500000000000000000000000001235451432000351715ustar00rootroot00000000000000randomizedtesting-release-2.1.6/junit4-ant/src/test/java/com/carrotsearch/ant/tasks/junit4/listeners/antxmlXmlStringTransformerAccess.java000066400000000000000000000003111235451432000433230ustar00rootroot00000000000000randomizedtesting-release-2.1.6/junit4-ant/src/test/java/com/carrotsearch/ant/tasks/junit4/listeners/antxmlpackage com.carrotsearch.ant.tasks.junit4.listeners.antxml; public class XmlStringTransformerAccess { public static XmlStringTransformer getInstance() { return new XmlStringTransformer(); } } randomizedtesting-release-2.1.6/junit4-ant/src/test/java/com/carrotsearch/ant/tasks/junit4/spikes/000077500000000000000000000000001235451432000332335ustar00rootroot00000000000000LocalRun.java000066400000000000000000000023501235451432000355360ustar00rootroot00000000000000randomizedtesting-release-2.1.6/junit4-ant/src/test/java/com/carrotsearch/ant/tasks/junit4/spikespackage com.carrotsearch.ant.tasks.junit4.spikes; import java.io.RandomAccessFile; import java.util.Date; @SuppressWarnings("resource") public class LocalRun { public static void main(String[] args) throws Exception { System.out.println("Live and prosper."); // make sure to delete raf first. final RandomAccessFile raf = new RandomAccessFile("shared.log", "rw"); final RandomAccessFile raf2 = new RandomAccessFile("shared.log", "r"); Thread t1 = new Thread() { @Override public void run() { while (true) { try { int c = raf2.read(); if (c == -1) { Thread.sleep(500); continue; } System.out.write(c); System.out.flush(); } catch (Exception e) { e.printStackTrace(); } } } }; Thread t2 = new Thread() { @Override public void run() { try { while (true) { raf.write((new Date().toString() + "\n").getBytes("UTF-8")); Thread.sleep(2000); } } catch (Exception e) { e.printStackTrace(); } } }; t1.start(); t2.start(); } } randomizedtesting-release-2.1.6/junit4-ant/src/test/java/com/carrotsearch/ant/tasks/junit4/tests/000077500000000000000000000000001235451432000330775ustar00rootroot00000000000000ChildVmSysprops.java000066400000000000000000000007241235451432000367770ustar00rootroot00000000000000randomizedtesting-release-2.1.6/junit4-ant/src/test/java/com/carrotsearch/ant/tasks/junit4/testspackage com.carrotsearch.ant.tasks.junit4.tests; import java.io.File; import org.junit.Assert; import org.junit.Test; public class ChildVmSysprops { @Test public void cwd() { Assert.assertNotNull(System.getProperty("junit4.childvm.cwd")); Assert.assertTrue(new File(System.getProperty("junit4.childvm.cwd")).isDirectory()); } @Test public void id() { Assert.assertNotNull(Integer.parseInt(System.getProperty("junit4.childvm.id"))); } } Crash.java000066400000000000000000000011001235451432000347130ustar00rootroot00000000000000randomizedtesting-release-2.1.6/junit4-ant/src/test/java/com/carrotsearch/ant/tasks/junit4/testspackage com.carrotsearch.ant.tasks.junit4.tests; public class Crash { public static native void crashMe(); public static void loadLibrary() { StringBuilder b = new StringBuilder("Could not link with crashlib."); try { System.loadLibrary("crash"); return; } catch (UnsatisfiedLinkError e) { b.append("\n").append(e.toString()); } try { System.loadLibrary("crash64"); return; } catch (UnsatisfiedLinkError e) { b.append("\n").append(e.toString()); } throw new UnsatisfiedLinkError(b.toString()); } } CwdConflict1.java000066400000000000000000000005251235451432000361450ustar00rootroot00000000000000randomizedtesting-release-2.1.6/junit4-ant/src/test/java/com/carrotsearch/ant/tasks/junit4/testspackage com.carrotsearch.ant.tasks.junit4.tests; import java.io.File; import org.junit.Test; public class CwdConflict1 { @Test public void testCreateConflictingFile() throws Exception { File file = new File("cwdconflict.tmp"); if (!file.createNewFile()) { throw new RuntimeException("File already exists."); } } } CwdConflict2.java000066400000000000000000000001461235451432000361450ustar00rootroot00000000000000randomizedtesting-release-2.1.6/junit4-ant/src/test/java/com/carrotsearch/ant/tasks/junit4/testspackage com.carrotsearch.ant.tasks.junit4.tests; public class CwdConflict2 extends CwdConflict1 { } DisabledGroup.java000066400000000000000000000006101235451432000364040ustar00rootroot00000000000000randomizedtesting-release-2.1.6/junit4-ant/src/test/java/com/carrotsearch/ant/tasks/junit4/testspackage com.carrotsearch.ant.tasks.junit4.tests; import java.lang.annotation.*; import com.carrotsearch.randomizedtesting.annotations.TestGroup; @Documented @Retention(RetentionPolicy.RUNTIME) @Target({ElementType.METHOD, ElementType.TYPE}) @Inherited @TestGroup(enabled = false) public @interface DisabledGroup { /** Additional description, if needed. */ String value() default ""; } EscapeSequences.java000066400000000000000000000003121235451432000367330ustar00rootroot00000000000000randomizedtesting-release-2.1.6/junit4-ant/src/test/java/com/carrotsearch/ant/tasks/junit4/testspackage com.carrotsearch.ant.tasks.junit4.tests; import org.junit.Test; public class EscapeSequences { @Test public void emitEscape() { System.out.print("stdout: foo & bar"); } } FailInAfterClass.java000066400000000000000000000005551235451432000370020ustar00rootroot00000000000000randomizedtesting-release-2.1.6/junit4-ant/src/test/java/com/carrotsearch/ant/tasks/junit4/testspackage com.carrotsearch.ant.tasks.junit4.tests; import org.junit.AfterClass; import org.junit.Test; public class FailInAfterClass { public final static String MESSAGE = "This is @AfterClass output."; @Test public void dummy() {} @AfterClass public static void afterClass() { System.out.println(MESSAGE); throw new RuntimeException(); } } FileEncoding.java000066400000000000000000000015061235451432000362130ustar00rootroot00000000000000randomizedtesting-release-2.1.6/junit4-ant/src/test/java/com/carrotsearch/ant/tasks/junit4/testspackage com.carrotsearch.ant.tasks.junit4.tests; import java.io.*; import java.nio.charset.Charset; import org.junit.Test; public class FileEncoding { @Test public void checkFileEncoding() throws IOException { ByteArrayOutputStream baos = new ByteArrayOutputStream(); PrintStream ps = new PrintStream(baos); ps.println("unicode string=cześć, Привет, 今日ã¯"); ps.close(); String encoding = System.getProperty("file.encoding"); System.out.println("file.encoding=" + encoding); System.out.println("charset=" + Charset.defaultCharset()); System.out.println("unicode string in " + encoding + "=cześć, Привет, 今日ã¯"); System.out.println("unicode string PrintStream'ed: " + baos.size() + " bytes, hex dump:"); HexDump.dump(baos.toByteArray(), 0, System.out, 0); } } FireUnhandledRunnerException.java000066400000000000000000000005621235451432000414470ustar00rootroot00000000000000randomizedtesting-release-2.1.6/junit4-ant/src/test/java/com/carrotsearch/ant/tasks/junit4/testspackage com.carrotsearch.ant.tasks.junit4.tests; import org.junit.Test; import com.carrotsearch.ant.tasks.junit4.slave.SlaveMain; public class FireUnhandledRunnerException { public static final String EXCEPTION_MESSAGE = "BAMBOOOOOCHA!"; @Test public void polluteRunner() { System.setProperty(SlaveMain.SYSPROP_FIRERUNNERFAILURE, EXCEPTION_MESSAGE); } } HeartbeatSlow.java000066400000000000000000000003671235451432000364350ustar00rootroot00000000000000randomizedtesting-release-2.1.6/junit4-ant/src/test/java/com/carrotsearch/ant/tasks/junit4/testspackage com.carrotsearch.ant.tasks.junit4.tests; import java.util.concurrent.TimeUnit; import org.junit.Test; public class HeartbeatSlow { @Test public void method1() throws Exception { Thread.sleep(TimeUnit.SECONDS.toMillis(3)); } } HexDump.java000066400000000000000000000117351235451432000352440ustar00rootroot00000000000000randomizedtesting-release-2.1.6/junit4-ant/src/test/java/com/carrotsearch/ant/tasks/junit4/testspackage com.carrotsearch.ant.tasks.junit4.tests; import java.io.IOException; import java.io.OutputStream; /** * Dumps data in hexadecimal format. *

* Provides a single function to take an array of bytes and display it * in hexadecimal form. *

* Origin of code: POI. * * @author Scott Sanders * @author Marc Johnson * @version $Id: HexDump.java 736507 2009-01-22 00:52:15Z jukka $ */ public class HexDump { /** * Instances should NOT be constructed in standard programming. */ public HexDump() { super(); } /** * Dump an array of bytes to an OutputStream. The output is formatted * for human inspection, with a hexadecimal offset followed by the * hexadecimal values of the next 16 bytes of data and the printable ASCII * characters (if any) that those bytes represent printed per each line * of output. *

* The offset argument specifies the start offset of the data array * within a larger entity like a file or an incoming stream. For example, * if the data array contains the third kibibyte of a file, then the * offset argument should be set to 2048. The offset value printed * at the beginning of each line indicates where in that larger entity * the first byte on that line is located. *

* All bytes between the given index (inclusive) and the end of the * data array are dumped. * * @param data the byte array to be dumped * @param offset offset of the byte array within a larger entity * @param stream the OutputStream to which the data is to be * written * @param index initial index into the byte array * * @throws IOException is thrown if anything goes wrong writing * the data to stream * @throws ArrayIndexOutOfBoundsException if the index is * outside the data array's bounds * @throws IllegalArgumentException if the output stream is null */ public static void dump(byte[] data, long offset, OutputStream stream, int index) throws IOException, ArrayIndexOutOfBoundsException, IllegalArgumentException { if ((index < 0) || (index >= data.length)) { throw new ArrayIndexOutOfBoundsException( "illegal index: " + index + " into array of length " + data.length); } if (stream == null) { throw new IllegalArgumentException("cannot write to nullstream"); } long display_offset = offset + index; StringBuilder buffer = new StringBuilder(74); for (int j = index; j < data.length; j += 16) { int chars_read = data.length - j; if (chars_read > 16) { chars_read = 16; } dump(buffer, display_offset).append(' '); for (int k = 0; k < 16; k++) { if (k < chars_read) { dump(buffer, data[k + j]); } else { buffer.append(" "); } buffer.append(' '); } for (int k = 0; k < chars_read; k++) { if ((data[k + j] >= ' ') && (data[k + j] < 127)) { buffer.append((char) data[k + j]); } else { buffer.append('.'); } } buffer.append(EOL); stream.write(buffer.toString().getBytes()); stream.flush(); buffer.setLength(0); display_offset += chars_read; } } /** * The line-separator (initializes to "line.separator" system property. */ public static final String EOL = System.getProperty("line.separator"); private static final char[] _hexcodes = { '0', '1', '2', '3', '4', '5', '6', '7', '8', '9', 'A', 'B', 'C', 'D', 'E', 'F' }; private static final int[] _shifts = { 28, 24, 20, 16, 12, 8, 4, 0 }; /** * Dump a long value into a StringBuilder. * * @param _lbuffer the StringBuilder to dump the value in * @param value the long value to be dumped * @return StringBuilder containing the dumped value. */ private static StringBuilder dump(StringBuilder _lbuffer, long value) { for (int j = 0; j < 8; j++) { _lbuffer .append(_hexcodes[((int) (value >> _shifts[j])) & 15]); } return _lbuffer; } /** * Dump a byte value into a StringBuilder. * * @param _cbuffer the StringBuilder to dump the value in * @param value the byte value to be dumped * @return StringBuilder containing the dumped value. */ private static StringBuilder dump(StringBuilder _cbuffer, byte value) { for (int j = 0; j < 2; j++) { _cbuffer.append(_hexcodes[(value >> _shifts[j + 6]) & 15]); } return _cbuffer; } } NotInstantiable.java000066400000000000000000000004321235451432000367600ustar00rootroot00000000000000randomizedtesting-release-2.1.6/junit4-ant/src/test/java/com/carrotsearch/ant/tasks/junit4/testspackage com.carrotsearch.ant.tasks.junit4.tests; import org.junit.Test; @SuppressWarnings("all") public class NotInstantiable { static { System.out.println("Can't instantiate me." + 1 / ((Long) null)); } public NotInstantiable() {} @Test public void method() {} } OomCode.java000066400000000000000000000007741235451432000352200ustar00rootroot00000000000000randomizedtesting-release-2.1.6/junit4-ant/src/test/java/com/carrotsearch/ant/tasks/junit4/testspackage com.carrotsearch.ant.tasks.junit4.tests; import java.util.LinkedList; import org.junit.Test; public class OomCode { static LinkedList ohMy = new LinkedList(); @Test public void oomInCode() { int stringLength = 1024 * 1024 * 5; while (true) { try { ohMy.add(new byte [stringLength]); } catch (OutOfMemoryError e) { if (stringLength < 100) { throw e; } else { stringLength /= 2; } } } } } OomPermGen.java000066400000000000000000000047471235451432000357070ustar00rootroot00000000000000randomizedtesting-release-2.1.6/junit4-ant/src/test/java/com/carrotsearch/ant/tasks/junit4/testspackage com.carrotsearch.ant.tasks.junit4.tests; import static org.objectweb.asm.Opcodes.ACC_PUBLIC; import static org.objectweb.asm.Opcodes.ACC_SUPER; import static org.objectweb.asm.Opcodes.ALOAD; import static org.objectweb.asm.Opcodes.INVOKESPECIAL; import static org.objectweb.asm.Opcodes.RETURN; import static org.objectweb.asm.Opcodes.V1_6; import java.lang.management.ManagementFactory; import java.lang.management.MemoryPoolMXBean; import java.util.ArrayList; import java.util.List; import java.util.Random; import org.junit.Assume; import org.junit.Test; import org.objectweb.asm.ClassWriter; import org.objectweb.asm.MethodVisitor; public class OomPermGen { abstract class WhoaClassLoader extends ClassLoader { public abstract Class defineNewClass(byte [] clazz) throws ClassNotFoundException; } WhoaClassLoader cl = new WhoaClassLoader() { public Class defineNewClass(byte [] clazz) throws ClassNotFoundException { return super.defineClass(null, clazz, 0, clazz.length); } }; @Test public void explodePermGen() throws Exception { MemoryPoolMXBean permGenPool = null; for (MemoryPoolMXBean mp : ManagementFactory.getMemoryPoolMXBeans()) { if (mp.getName().contains("Perm Gen")) { permGenPool = mp; break; } } if (permGenPool == null) { // No permgen pool? Assume.assumeTrue(false); } // Just keep on loading classes until we explode. Random rnd = new Random(0xdeadbeef); int classes = 0; List> keep = new ArrayList>(); while (true) { if ((classes++ % 1000) == 0) { System.out.println(permGenPool.getName() + " => " + permGenPool.getUsage()); } // Prepare a new unique exception class with asm. Throw it. Class clz = generateExceptionClass(rnd.nextLong()); clz.newInstance(); keep.add(clz); } } public Class generateExceptionClass(long x) throws Exception { ClassWriter cw = new ClassWriter(0); MethodVisitor mv; cw.visit(V1_6, ACC_PUBLIC + ACC_SUPER, "com/carrotsearch/ant/tasks/junit4/tests/SyntheticException_" + x, null, "java/lang/Exception", null); mv = cw.visitMethod(ACC_PUBLIC, "", "()V", null, null); mv.visitCode(); mv.visitVarInsn(ALOAD, 0); mv.visitMethodInsn(INVOKESPECIAL, "java/lang/Exception", "", "()V"); mv.visitInsn(RETURN); mv.visitMaxs(1, 1); mv.visitEnd(); cw.visitEnd(); return cl.defineNewClass(cw.toByteArray()); } } OutOfOrderSysouts.java000066400000000000000000000032111235451432000373220ustar00rootroot00000000000000randomizedtesting-release-2.1.6/junit4-ant/src/test/java/com/carrotsearch/ant/tasks/junit4/testspackage com.carrotsearch.ant.tasks.junit4.tests; import org.junit.*; import com.carrotsearch.randomizedtesting.RandomizedTest; import com.carrotsearch.randomizedtesting.annotations.ThreadLeakScope; import com.carrotsearch.randomizedtesting.annotations.ThreadLeakScope.Scope; @ThreadLeakScope(Scope.SUITE) public class OutOfOrderSysouts extends RandomizedTest { private static Thread t; static { t = new Thread("background-non-daemon") { public void run() { sysout("Starting..."); try { while (true) { syserr("garbage..."); Thread.sleep(1); } } catch (Exception e) { // empty. } } }; t.start(); } @Before public void before() { sleep(1 + randomInt(20)); } @AfterClass public static void afterClass() throws Exception { t.interrupt(); t.join(); } @Test public void method1() { sysout("method1"); } @Test public void method2() { sysout("method2"); } @Test public void method3() { sysout("method3"); } @Test public void method4() { sysout("method4"); } @Test public void method5() { sysout("method5"); } @Test public void method6() { sysout("method6"); } @Test public void method7() { sysout("method7"); } @Test public void method8() { sysout("method8"); } @Test public void method9() { sysout("method9"); } @Test public void method10() { sysout("method10"); } @Test public void method11() { sysout("method11"); } static void sysout(String msg) { System.out.println(msg); System.out.flush(); } static void syserr(String msg) { System.out.println(msg); System.out.flush(); } } RandomSysProperty.java000066400000000000000000000005471235451432000373550ustar00rootroot00000000000000randomizedtesting-release-2.1.6/junit4-ant/src/test/java/com/carrotsearch/ant/tasks/junit4/testspackage com.carrotsearch.ant.tasks.junit4.tests; import org.junit.Test; public class RandomSysProperty { @Test public void test1() { for (String s : new String [] { "prefix.dummy1", "prefix.dummy2", "replaced.dummy1", "replaced.dummy2", }) { System.out.println(s + "=" + System.getProperty(s)); } } } ReasonForAssumptionIgnored.java000066400000000000000000000015311235451432000411540ustar00rootroot00000000000000randomizedtesting-release-2.1.6/junit4-ant/src/test/java/com/carrotsearch/ant/tasks/junit4/testspackage com.carrotsearch.ant.tasks.junit4.tests; import org.junit.BeforeClass; import org.junit.Test; import org.junit.runner.RunWith; import com.carrotsearch.ant.tasks.junit4.it.TestTextReport; import com.carrotsearch.randomizedtesting.RandomizedRunner; import com.carrotsearch.randomizedtesting.RandomizedTest; /** * Holder class for tests used in * {@link TestTextReport#reasonForSuiteAssumptionIgnored()}. */ public class ReasonForAssumptionIgnored { public final static String MESSAGE = "FooBar"; @RunWith(RandomizedRunner.class) public static class IgnoredClassRR extends IgnoredClass { } public static class IgnoredClass { @BeforeClass public static void beforeClass() { RandomizedTest.assumeTrue(MESSAGE, false); } @Test public void ignored1() {} @Test public void ignored2() {} } } ReasonForIgnored.java000066400000000000000000000023761235451432000371010ustar00rootroot00000000000000randomizedtesting-release-2.1.6/junit4-ant/src/test/java/com/carrotsearch/ant/tasks/junit4/testspackage com.carrotsearch.ant.tasks.junit4.tests; import org.junit.Ignore; import org.junit.Test; import org.junit.runner.RunWith; import com.carrotsearch.ant.tasks.junit4.it.TestTextReport; import com.carrotsearch.randomizedtesting.RandomizedRunner; /** * Holder class for tests used in {@link TestTextReport#reasonForIgnored()}. */ public class ReasonForIgnored { public static class IgnoredMethods { @Test @Ignore public void simplyIgnored() { } @Test @Ignore("Ignored method.") public void ignoredWithRationale() { } } @Ignore("Ignored class.") public static class IgnoredClass { @Test public void ignoredByClass() { System.out.println("Hello!"); } } @RunWith(RandomizedRunner.class) public static class IgnoredMethodsRR extends IgnoredMethods { @Test @Ignore("Ignored method (2).") public void ignoredAgain() { } } @Ignore("Ignored class.") @RunWith(RandomizedRunner.class) public static class IgnoredClassRR extends IgnoredClass { } @RunWith(RandomizedRunner.class) public static class IgnoredGroup { @DisabledGroup @Test public void ignoredByGroup() {} } } ReasonForIgnoredByDisabledGroup.java000066400000000000000000000004221235451432000420270ustar00rootroot00000000000000randomizedtesting-release-2.1.6/junit4-ant/src/test/java/com/carrotsearch/ant/tasks/junit4/testspackage com.carrotsearch.ant.tasks.junit4.tests; import org.junit.Test; import com.carrotsearch.randomizedtesting.RandomizedTest; public class ReasonForIgnoredByDisabledGroup extends RandomizedTest { @Test @DisabledGroup("foo bar") public void disabledGroup() {} } ShutdownHook.java000066400000000000000000000007621235451432000363240ustar00rootroot00000000000000randomizedtesting-release-2.1.6/junit4-ant/src/test/java/com/carrotsearch/ant/tasks/junit4/testspackage com.carrotsearch.ant.tasks.junit4.tests; import org.junit.Test; public class ShutdownHook { @Test public void testShutdownHook() { Runtime.getRuntime().addShutdownHook(new Thread() { public void run() { // Delay by about a minute. long deadline = System.currentTimeMillis() + 60 * 1000; while (System.currentTimeMillis() < deadline) { try { Thread.sleep(1000); } catch (Exception e) {} } } }); } } SlaveHangingBackgroundThreads.java000066400000000000000000000014431235451432000415460ustar00rootroot00000000000000randomizedtesting-release-2.1.6/junit4-ant/src/test/java/com/carrotsearch/ant/tasks/junit4/testspackage com.carrotsearch.ant.tasks.junit4.tests; import java.util.concurrent.CountDownLatch; import org.junit.Test; public class SlaveHangingBackgroundThreads { static { final CountDownLatch latch = new CountDownLatch(1); new Thread("background-non-daemon") { public void run() { System.out.println("Starting."); try { latch.countDown(); // Wait looong. Thread.sleep(1000 * 60 * 60); } catch (Exception e) { // empty. } } }.start(); try { latch.await(); } catch (InterruptedException e) { throw new RuntimeException(e); } // Cause an unchecked exception. @SuppressWarnings("unused") int a = 2 / 0; } @Test public void method() { // Ok, passes. } } StackOverflow.java000066400000000000000000000010071235451432000364520ustar00rootroot00000000000000randomizedtesting-release-2.1.6/junit4-ant/src/test/java/com/carrotsearch/ant/tasks/junit4/testspackage com.carrotsearch.ant.tasks.junit4.tests; import org.junit.Test; public class StackOverflow { @Test public void stackoverflow() { for (int i = 0; i < 100; i++) { try { doStackOverflowAndPrint(0); } catch (StackOverflowError e) { // Should have failed inside the runner's infrastructure? } } System.exit(0); } private void doStackOverflowAndPrint(int i) { System.out.println("Stack overflow attempt: " + i); doStackOverflowAndPrint(i + 1); } } SuiteListeners.java000066400000000000000000000033661235451432000366550ustar00rootroot00000000000000randomizedtesting-release-2.1.6/junit4-ant/src/test/java/com/carrotsearch/ant/tasks/junit4/testspackage com.carrotsearch.ant.tasks.junit4.tests; import org.junit.Ignore; import org.junit.Test; import org.junit.runner.Description; import org.junit.runner.Result; import org.junit.runner.notification.Failure; import org.junit.runner.notification.RunListener; import com.carrotsearch.randomizedtesting.RandomizedTest; import com.carrotsearch.randomizedtesting.annotations.Listeners; @Listeners({ SuiteListeners.PrintEventListener.class }) public class SuiteListeners extends RandomizedTest { public static class PrintEventListener extends RunListener { @Override public void testRunStarted(Description description) throws Exception { System.out.println("testRunStarted: " + description); } @Override public void testRunFinished(Result result) throws Exception { System.out.println("testRunFinished."); } @Override public void testStarted(Description description) throws Exception { System.out.println("testStarted: " + description); } @Override public void testFinished(Description description) throws Exception { System.out.println("testFinished: " + description); } @Override public void testFailure(Failure failure) throws Exception { System.out.println("testFailure: " + failure); } @Override public void testAssumptionFailure(Failure failure) { System.out.println("testAssumptionFailure: " + failure); } @Override public void testIgnored(Description description) throws Exception { System.out.println("testIgnored: " + description); } } @Test public void passing() {} @Test @Ignore public void ignored() {} @Test public void aignored() { assumeTrue(false); } @Test public void failure() { fail(); } } SysPropertySets.java000066400000000000000000000004111235451432000370410ustar00rootroot00000000000000randomizedtesting-release-2.1.6/junit4-ant/src/test/java/com/carrotsearch/ant/tasks/junit4/testspackage com.carrotsearch.ant.tasks.junit4.tests; import org.junit.Test; public class SysPropertySets { @Test public void test1() { System.out.println(System.getProperty("prefix.dummy1")); System.out.println(System.getProperty("prefix.dummy2")); } } SysoutOom1.java000066400000000000000000000010211235451432000357170ustar00rootroot00000000000000randomizedtesting-release-2.1.6/junit4-ant/src/test/java/com/carrotsearch/ant/tasks/junit4/testspackage com.carrotsearch.ant.tasks.junit4.tests; import org.junit.Test; public class SysoutOom1 { @Test public void writealot() { write("012345678901234567890123456789".toCharArray()); } protected final void write(char[] charArray) { char [] chars = new char [200]; for (int i = 0; i < chars.length; i++) { chars[i] = charArray[i % charArray.length]; } int emitChars = 1024 * 1024 * 25; while (emitChars > 0) { System.out.print(chars); emitChars -= chars.length; } } } SysoutOom2.java000066400000000000000000000003661235451432000357330ustar00rootroot00000000000000randomizedtesting-release-2.1.6/junit4-ant/src/test/java/com/carrotsearch/ant/tasks/junit4/testspackage com.carrotsearch.ant.tasks.junit4.tests; import org.junit.Test; public class SysoutOom2 extends SysoutOom1 { @Override @Test public void writealot() { write("abcdefghjqiuqiugqwpicvaisuvcipsvcuipqyfpuixv".toCharArray()); } } SysoutPassthrough.java000066400000000000000000000016211235451432000374210ustar00rootroot00000000000000randomizedtesting-release-2.1.6/junit4-ant/src/test/java/com/carrotsearch/ant/tasks/junit4/testspackage com.carrotsearch.ant.tasks.junit4.tests; import org.junit.After; import org.junit.AfterClass; import org.junit.Before; import org.junit.BeforeClass; import org.junit.Test; public class SysoutPassthrough { @BeforeClass public static void beforeclass() { println("-beforeclass-"); } @Before public void before() { println("-before-"); } @Test public void test1() { println("-test1-"); } @Test public void test2() { println("-test2-"); } @After public void after() { print("-after-"); } @AfterClass public static void afterclass() { println("-afterclass-"); } private static void print(String m) { System.out.print(m); System.out.flush(); try { Thread.sleep(1000); } catch (InterruptedException e) { throw new RuntimeException(); } } private static void println(String m) { print(m + "\n"); } } SysoutsOnSuiteFailure.java000066400000000000000000000012061235451432000401720ustar00rootroot00000000000000randomizedtesting-release-2.1.6/junit4-ant/src/test/java/com/carrotsearch/ant/tasks/junit4/testspackage com.carrotsearch.ant.tasks.junit4.tests; import org.junit.AfterClass; import org.junit.Assume; import org.junit.BeforeClass; import org.junit.Test; public class SysoutsOnSuiteFailure { @BeforeClass public static void beforeClass() { System.out.println("beforeclass-sysout."); } @Test public void assumptionIgnored() { System.out.println("ignored-sysout."); Assume.assumeTrue(false); } @Test public void success() { System.out.println("success-sysout."); } @AfterClass public static void afterClass() { System.out.println("afterclass-sysout."); throw new RuntimeException(); } } SysoutsOnSuiteTimeout.java000066400000000000000000000023011235451432000402260ustar00rootroot00000000000000randomizedtesting-release-2.1.6/junit4-ant/src/test/java/com/carrotsearch/ant/tasks/junit4/testspackage com.carrotsearch.ant.tasks.junit4.tests; import org.junit.BeforeClass; import org.junit.Test; import com.carrotsearch.randomizedtesting.RandomizedTest; import com.carrotsearch.randomizedtesting.annotations.ThreadLeakAction; import com.carrotsearch.randomizedtesting.annotations.ThreadLeakAction.Action; import com.carrotsearch.randomizedtesting.annotations.ThreadLeakGroup; import com.carrotsearch.randomizedtesting.annotations.ThreadLeakGroup.Group; import com.carrotsearch.randomizedtesting.annotations.ThreadLeakLingering; import com.carrotsearch.randomizedtesting.annotations.ThreadLeakScope; import com.carrotsearch.randomizedtesting.annotations.ThreadLeakScope.Scope; import com.carrotsearch.randomizedtesting.annotations.TimeoutSuite; @ThreadLeakScope(Scope.SUITE) @ThreadLeakGroup(Group.MAIN) @ThreadLeakAction({Action.WARN, Action.INTERRUPT}) @ThreadLeakLingering(linger = 1000) @TimeoutSuite(millis = 1000) public class SysoutsOnSuiteTimeout extends RandomizedTest { @BeforeClass public static void beforeClass() { System.out.println("beforeclass-sysout."); } @Test public void success() throws Exception { System.out.println("test-sysout."); Thread.sleep(100000); } } TestAfterClassError.java000066400000000000000000000004071235451432000375650ustar00rootroot00000000000000randomizedtesting-release-2.1.6/junit4-ant/src/test/java/com/carrotsearch/ant/tasks/junit4/testspackage com.carrotsearch.ant.tasks.junit4.tests; import org.junit.AfterClass; import org.junit.Test; public class TestAfterClassError { @AfterClass public static void afterClass() { throw new RuntimeException(); } @Test public void method() {} } TestBeforeClassError.java000066400000000000000000000004131235451432000377230ustar00rootroot00000000000000randomizedtesting-release-2.1.6/junit4-ant/src/test/java/com/carrotsearch/ant/tasks/junit4/testspackage com.carrotsearch.ant.tasks.junit4.tests; import org.junit.BeforeClass; import org.junit.Test; public class TestBeforeClassError { @BeforeClass public static void beforeClass() { throw new RuntimeException(); } @Test public void method() {} } TestDir.java000066400000000000000000000003721235451432000352430ustar00rootroot00000000000000randomizedtesting-release-2.1.6/junit4-ant/src/test/java/com/carrotsearch/ant/tasks/junit4/testspackage com.carrotsearch.ant.tasks.junit4.tests; import java.io.File; import java.io.IOException; import org.junit.Test; public class TestDir { @Test public void createDir() throws IOException { new File("touch.me").createNewFile(); } } TestEnvVar.java000066400000000000000000000005511235451432000357250ustar00rootroot00000000000000randomizedtesting-release-2.1.6/junit4-ant/src/test/java/com/carrotsearch/ant/tasks/junit4/testspackage com.carrotsearch.ant.tasks.junit4.tests; import java.io.IOException; import org.junit.Assert; import org.junit.Test; public class TestEnvVar { /** * Check environment property passing. */ @Test public void testEnvVar() throws IOException { String value = System.getenv("env.variable"); Assert.assertEquals("foobar", value); } } TestEscaping.java000066400000000000000000000014611235451432000362560ustar00rootroot00000000000000randomizedtesting-release-2.1.6/junit4-ant/src/test/java/com/carrotsearch/ant/tasks/junit4/testspackage com.carrotsearch.ant.tasks.junit4.tests; import org.junit.Assert; import org.junit.Test; public class TestEscaping { @Test public void checkEscapes() { // success it is. System.out.println(System.getProperty("sysprop.key")); System.out.println(System.getProperty("sysprop.key2")); System.out.println(System.getProperty("sysprop.key3")); System.out.println(System.getenv("env.variable")); Assert.assertEquals("${nonexistent-1}", System.getProperty("sysprop.key")); Assert.assertEquals("abc def", System.getProperty("sysprop.key2")); Assert.assertEquals("%PATH%", System.getProperty("sysprop.key3")); Assert.assertEquals("${nonexistent-3}", System.getenv("env.variable")); } public static void main(String[] args) { new TestEscaping().checkEscapes(); } } TestFailureTypePassing.java000066400000000000000000000027671235451432000403150ustar00rootroot00000000000000randomizedtesting-release-2.1.6/junit4-ant/src/test/java/com/carrotsearch/ant/tasks/junit4/testspackage com.carrotsearch.ant.tasks.junit4.tests; import static org.objectweb.asm.Opcodes.ACC_PUBLIC; import static org.objectweb.asm.Opcodes.ACC_SUPER; import static org.objectweb.asm.Opcodes.ALOAD; import static org.objectweb.asm.Opcodes.INVOKESPECIAL; import static org.objectweb.asm.Opcodes.RETURN; import static org.objectweb.asm.Opcodes.V1_6; import org.junit.Test; import org.objectweb.asm.ClassWriter; import org.objectweb.asm.MethodVisitor; public class TestFailureTypePassing { @Test public void nonStandardError() throws Exception { // Prepare a new unique exception class with asm. Throw it. Class clz = generateExceptionClass(); throw Exception.class.cast(clz.newInstance()); } public static Class generateExceptionClass() throws Exception { ClassWriter cw = new ClassWriter(0); MethodVisitor mv; cw.visit(V1_6, ACC_PUBLIC + ACC_SUPER, "com/carrotsearch/ant/tasks/junit4/tests/SyntheticException", null, "java/lang/Exception", null); mv = cw.visitMethod(ACC_PUBLIC, "", "()V", null, null); mv.visitCode(); mv.visitVarInsn(ALOAD, 0); mv.visitMethodInsn(INVOKESPECIAL, "java/lang/Exception", "", "()V"); mv.visitInsn(RETURN); mv.visitMaxs(1, 1); mv.visitEnd(); cw.visitEnd(); return new ClassLoader() { public Class defineNewClass(byte [] clazz) throws ClassNotFoundException { return super.defineClass(null, clazz, 0, clazz.length); } }.defineNewClass(cw.toByteArray()); } } TestFilteringExpressions.java000066400000000000000000000025271235451432000407170ustar00rootroot00000000000000randomizedtesting-release-2.1.6/junit4-ant/src/test/java/com/carrotsearch/ant/tasks/junit4/testspackage com.carrotsearch.ant.tasks.junit4.tests; import java.lang.annotation.ElementType; import java.lang.annotation.Inherited; import java.lang.annotation.Retention; import java.lang.annotation.RetentionPolicy; import java.lang.annotation.Target; import org.junit.Test; import com.carrotsearch.randomizedtesting.RandomizedTest; import com.carrotsearch.randomizedtesting.annotations.TestGroup; public class TestFilteringExpressions { @Retention(RetentionPolicy.RUNTIME) @Target({ElementType.METHOD, ElementType.TYPE}) @Inherited @TestGroup(enabled = false) public static @interface Foo {} @Retention(RetentionPolicy.RUNTIME) @Target({ElementType.METHOD, ElementType.TYPE}) @Inherited @TestGroup(enabled = false) public static @interface Bar {} public static class Example1 extends RandomizedTest { @Test @Foo public void testFoo() { System.out.println(">foo<"); } @Test @Foo @Bar public void testFooBar() { System.out.println(">foobar<"); } @Test @Bar public void testBar() { System.out.println(">bar<"); } } public static class Example2 extends RandomizedTest { @Test @Foo @Bar public void testFooBar() { System.out.println(">foobar2<"); } @Test @Bar public void testBar() { System.out.println(">bar2<"); } } } TestHierarchicalSuiteDescription.java000066400000000000000000000020041235451432000423130ustar00rootroot00000000000000randomizedtesting-release-2.1.6/junit4-ant/src/test/java/com/carrotsearch/ant/tasks/junit4/testspackage com.carrotsearch.ant.tasks.junit4.tests; import org.junit.AfterClass; import org.junit.BeforeClass; import org.junit.Test; import org.junit.runner.RunWith; import org.junit.runners.Suite; import org.junit.runners.Suite.SuiteClasses; @RunWith(Suite.class) @SuiteClasses({ TestHierarchicalSuiteDescription.Sub1.class, TestHierarchicalSuiteDescription.Sub2.class, TestHierarchicalSuiteDescription.Sub3.class }) public class TestHierarchicalSuiteDescription { public static class Sub1 { @Test public void method1() {} @BeforeClass public static void beforeClass() { throw new RuntimeException(); } } public static class Sub2 { @Test public void method1() {} @AfterClass public static void afterClass() { throw new RuntimeException(); } } public static class Sub3 { @Test public void method1() { throw new RuntimeException(); } } @AfterClass public static void afterClass() { throw new RuntimeException(); } } TestIgnoredSuite.java000066400000000000000000000005041235451432000371230ustar00rootroot00000000000000randomizedtesting-release-2.1.6/junit4-ant/src/test/java/com/carrotsearch/ant/tasks/junit4/testspackage com.carrotsearch.ant.tasks.junit4.tests; import org.junit.Ignore; import org.junit.Test; @Ignore public class TestIgnoredSuite { @Test public void method1() {} @Test public void method2() {} @Test public void method3() {} @Test public void method4() {} @Test public void method5() {} } TestInvalidUtfCharacter.java000066400000000000000000000004761235451432000404140ustar00rootroot00000000000000randomizedtesting-release-2.1.6/junit4-ant/src/test/java/com/carrotsearch/ant/tasks/junit4/testspackage com.carrotsearch.ant.tasks.junit4.tests; import org.junit.Test; public class TestInvalidUtfCharacter { @Test public void emitInvalidCharacter() throws Exception { String msg = "Invalid char: >\u0002< >\u0000<"; System.out.println(msg); System.out.flush(); throw new Exception(msg); } } TestJvmArg.java000066400000000000000000000004351235451432000357130ustar00rootroot00000000000000randomizedtesting-release-2.1.6/junit4-ant/src/test/java/com/carrotsearch/ant/tasks/junit4/testspackage com.carrotsearch.ant.tasks.junit4.tests; import org.junit.Assert; import org.junit.Test; public class TestJvmArg { /** * Check system property passing. */ @Test public void testJvmArg() { Assert.assertEquals("foobar", System.getProperty("test.param")); } } TestJvmCrash.java000066400000000000000000000006431235451432000362430ustar00rootroot00000000000000randomizedtesting-release-2.1.6/junit4-ant/src/test/java/com/carrotsearch/ant/tasks/junit4/testspackage com.carrotsearch.ant.tasks.junit4.tests; import java.io.IOException; import org.junit.Assert; import org.junit.Test; public class TestJvmCrash { /** * Check jvm crash. */ @Test public void testJvmCrash() throws IOException { // Try going into native mode first and cause a sigsegv. // This will work for any jvm (?). Crash.loadLibrary(); Crash.crashMe(); Assert.fail(); } } TestMaxMem.java000066400000000000000000000005331235451432000357100ustar00rootroot00000000000000randomizedtesting-release-2.1.6/junit4-ant/src/test/java/com/carrotsearch/ant/tasks/junit4/testspackage com.carrotsearch.ant.tasks.junit4.tests; import org.junit.Assert; import org.junit.Test; public class TestMaxMem { /** * Check max memory setting to be less than 100mb. */ @Test public void testMaxMemory() { long maxMemory = Runtime.getRuntime().maxMemory(); Assert.assertTrue(maxMemory / (1024 * 1024) < 110); } } TestReproduceString.java000066400000000000000000000007161235451432000376460ustar00rootroot00000000000000randomizedtesting-release-2.1.6/junit4-ant/src/test/java/com/carrotsearch/ant/tasks/junit4/testspackage com.carrotsearch.ant.tasks.junit4.tests; import org.junit.Assert; import org.junit.Test; import com.carrotsearch.randomizedtesting.RandomizedTest; import com.carrotsearch.randomizedtesting.annotations.Listeners; import com.carrotsearch.randomizedtesting.listeners.ReproduceInfoPrinter; @Listeners({ ReproduceInfoPrinter.class }) public class TestReproduceString extends RandomizedTest { @Test public void alwaysFail() { Assert.fail(); } } TestSeedPassing.java000066400000000000000000000016041235451432000367310ustar00rootroot00000000000000randomizedtesting-release-2.1.6/junit4-ant/src/test/java/com/carrotsearch/ant/tasks/junit4/testspackage com.carrotsearch.ant.tasks.junit4.tests; import java.io.IOException; import org.junit.Assert; import org.junit.Test; import com.carrotsearch.randomizedtesting.*; import static com.carrotsearch.randomizedtesting.SysGlobals.*; public class TestSeedPassing extends RandomizedTest { @Test public void checkSeedSet() throws IOException { Assert.assertEquals(System.getProperty(SYSPROP_RANDOM_SEED()), SeedUtils.formatSeedChain( new Randomness(0xdeadbeefL), new Randomness(0xcafebabeL)), System.getProperty(SYSPROP_RANDOM_SEED())); Assert.assertEquals( "[CAFEBABE]", SeedUtils.formatSeedChain(getContext().getRandomness())); Assert.assertEquals( "[DEADBEEF]", SeedUtils.formatSeedChain( new Randomness( SeedUtils.parseSeed(getContext().getRunnerSeedAsString())))); } } TestStaticScopeOutput.java000066400000000000000000000011671235451432000401720ustar00rootroot00000000000000randomizedtesting-release-2.1.6/junit4-ant/src/test/java/com/carrotsearch/ant/tasks/junit4/testspackage com.carrotsearch.ant.tasks.junit4.tests; import org.junit.AfterClass; import org.junit.BeforeClass; import org.junit.Test; /** * Static scope output. */ public class TestStaticScopeOutput { static { System.out.println("static-scope"); System.out.flush(); } @BeforeClass public static void beforeClass() { System.out.println("before-class"); System.out.flush(); } @Test public void testMethod() { System.out.println("test-method"); System.out.flush(); } @AfterClass public static void afterClass() { System.out.println("after-class"); System.out.flush(); } } TestStatuses.java000066400000000000000000000007301235451432000363360ustar00rootroot00000000000000randomizedtesting-release-2.1.6/junit4-ant/src/test/java/com/carrotsearch/ant/tasks/junit4/testspackage com.carrotsearch.ant.tasks.junit4.tests; import org.junit.Assert; import org.junit.Assume; import org.junit.Ignore; import org.junit.Test; public class TestStatuses { @Test public void ok() { } @Test @Ignore public void ignored() { } @Test public void ignored_a() { Assume.assumeTrue(false); } @Test public void failure() { Assert.assertTrue(false); } @Test public void error() { throw new RuntimeException(); } } TestSuccess.java000066400000000000000000000005761235451432000361430ustar00rootroot00000000000000randomizedtesting-release-2.1.6/junit4-ant/src/test/java/com/carrotsearch/ant/tasks/junit4/testspackage com.carrotsearch.ant.tasks.junit4.tests; import org.junit.Test; import com.carrotsearch.randomizedtesting.RandomizedTest; import com.carrotsearch.randomizedtesting.SeedUtils; public class TestSuccess extends RandomizedTest { @Test public void alwaysPasses() { System.out.println("Seed: " + SeedUtils.formatSeedChain(getContext().getRandomness())); } } TestSysstreams.java000066400000000000000000000006501235451432000367010ustar00rootroot00000000000000randomizedtesting-release-2.1.6/junit4-ant/src/test/java/com/carrotsearch/ant/tasks/junit4/testspackage com.carrotsearch.ant.tasks.junit4.tests; import org.junit.Test; public class TestSysstreams { @Test public void ok() {} @Test public void ok_sysout_syserr() { System.out.print("sysout"); System.out.flush(); System.err.print("syserr"); System.err.flush(); System.out.print("-sysout-contd."); System.out.flush(); System.err.print("-syserr-contd."); System.err.flush(); } } 000077500000000000000000000000001235451432000335465ustar00rootroot00000000000000randomizedtesting-release-2.1.6/junit4-ant/src/test/java/com/carrotsearch/ant/tasks/junit4/tests/badTestAbstract.java000066400000000000000000000002401235451432000370100ustar00rootroot00000000000000randomizedtesting-release-2.1.6/junit4-ant/src/test/java/com/carrotsearch/ant/tasks/junit4/tests/badpackage com.carrotsearch.ant.tasks.junit4.tests.bad; import org.junit.Test; public abstract class TestAbstract { @Test public void shouldBeIgnored() {} } TestPackagePrivate.java000066400000000000000000000001231235451432000401330ustar00rootroot00000000000000randomizedtesting-release-2.1.6/junit4-ant/src/test/java/com/carrotsearch/ant/tasks/junit4/tests/badpackage com.carrotsearch.ant.tasks.junit4.tests.bad; class TestPackagePrivate { } 000077500000000000000000000000001235451432000353315ustar00rootroot00000000000000randomizedtesting-release-2.1.6/junit4-ant/src/test/java/com/carrotsearch/ant/tasks/junit4/tests/replicationTestNonReplicated1.java000066400000000000000000000005331235451432000416450ustar00rootroot00000000000000randomizedtesting-release-2.1.6/junit4-ant/src/test/java/com/carrotsearch/ant/tasks/junit4/tests/replicationpackage com.carrotsearch.ant.tasks.junit4.tests.replication; import org.junit.Test; import com.carrotsearch.randomizedtesting.RandomizedTest; public class TestNonReplicated1 extends RandomizedTest { @Test public void nonReplicatedTest() { System.out.println("Non-replicated test, VM: " + System.getProperty("junit4.childvm.id")); } } TestNonReplicated2.java000066400000000000000000000005331235451432000416460ustar00rootroot00000000000000randomizedtesting-release-2.1.6/junit4-ant/src/test/java/com/carrotsearch/ant/tasks/junit4/tests/replicationpackage com.carrotsearch.ant.tasks.junit4.tests.replication; import org.junit.Test; import com.carrotsearch.randomizedtesting.RandomizedTest; public class TestNonReplicated2 extends RandomizedTest { @Test public void nonReplicatedTest() { System.out.println("Non-replicated test, VM: " + System.getProperty("junit4.childvm.id")); } } TestPseudoLoadBalancing.java000066400000000000000000000025101235451432000426700ustar00rootroot00000000000000randomizedtesting-release-2.1.6/junit4-ant/src/test/java/com/carrotsearch/ant/tasks/junit4/tests/replicationpackage com.carrotsearch.ant.tasks.junit4.tests.replication; import java.util.ArrayList; import java.util.List; import java.util.Locale; import org.junit.Before; import org.junit.Test; import com.carrotsearch.randomizedtesting.RandomizedTest; import com.carrotsearch.randomizedtesting.annotations.Name; import com.carrotsearch.randomizedtesting.annotations.ParametersFactory; import com.carrotsearch.randomizedtesting.annotations.ReplicateOnEachVm; @ReplicateOnEachVm public class TestPseudoLoadBalancing extends RandomizedTest { private int id; private int jvmId; private int jvms; public TestPseudoLoadBalancing(@Name("id") int id) { this.id = id; } @Before public void pseudoLoadBalancing() { jvmId = Integer.parseInt(System.getProperty("junit4.childvm.id")); jvms = Integer.parseInt(System.getProperty("junit4.childvm.count")); assumeTrue( String.format(Locale.ENGLISH, "Test %d ignored on VM %d.", id, jvmId), (id % jvms) == jvmId); } @Test public void replicatedTest() { System.out.println(String.format(Locale.ENGLISH, "Test %d executed on VM %d.", id, jvmId)); } @ParametersFactory public static Iterable parameters() { List args = new ArrayList(); for (int i = 0; i < 100; i++) { args.add($(i)); } return args; } } TestSuiteReplicated.java000066400000000000000000000006611235451432000421250ustar00rootroot00000000000000randomizedtesting-release-2.1.6/junit4-ant/src/test/java/com/carrotsearch/ant/tasks/junit4/tests/replicationpackage com.carrotsearch.ant.tasks.junit4.tests.replication; import org.junit.Test; import com.carrotsearch.randomizedtesting.RandomizedTest; import com.carrotsearch.randomizedtesting.annotations.ReplicateOnEachVm; @ReplicateOnEachVm public class TestSuiteReplicated extends RandomizedTest { @Test public void replicatedTest() { System.out.println("Replicated test, VM: " + System.getProperty("junit4.childvm.id")); } } 000077500000000000000000000000001235451432000336725ustar00rootroot00000000000000randomizedtesting-release-2.1.6/junit4-ant/src/test/java/com/carrotsearch/ant/tasks/junit4/tests/sub1TestAssertions.java000066400000000000000000000002721235451432000375300ustar00rootroot00000000000000randomizedtesting-release-2.1.6/junit4-ant/src/test/java/com/carrotsearch/ant/tasks/junit4/tests/sub1package com.carrotsearch.ant.tasks.junit4.tests.sub1; import org.junit.Test; public class TestAssertions { @Test public void failOnAssertion() { assert false : "foobar"; } } 000077500000000000000000000000001235451432000336735ustar00rootroot00000000000000randomizedtesting-release-2.1.6/junit4-ant/src/test/java/com/carrotsearch/ant/tasks/junit4/tests/sub2TestHalfSecond.java000066400000000000000000000003001235451432000373750ustar00rootroot00000000000000randomizedtesting-release-2.1.6/junit4-ant/src/test/java/com/carrotsearch/ant/tasks/junit4/tests/sub2package com.carrotsearch.ant.tasks.junit4.tests.sub2; import org.junit.Test; public class TestHalfSecond { @Test public void halfSecond() throws Exception { Thread.sleep(500); } } TestOneSecond.java000066400000000000000000000007131235451432000372540ustar00rootroot00000000000000randomizedtesting-release-2.1.6/junit4-ant/src/test/java/com/carrotsearch/ant/tasks/junit4/tests/sub2package com.carrotsearch.ant.tasks.junit4.tests.sub2; import org.junit.Test; public class TestOneSecond { @Test public void quarterSecond1() throws Exception { Thread.sleep(250); } @Test public void quarterSecond2() throws Exception { Thread.sleep(250); } @Test public void quarterSecond3() throws Exception { Thread.sleep(250); } @Test public void quarterSecond4() throws Exception { Thread.sleep(250); } } TestTwoSeconds.java000066400000000000000000000004261235451432000374700ustar00rootroot00000000000000randomizedtesting-release-2.1.6/junit4-ant/src/test/java/com/carrotsearch/ant/tasks/junit4/tests/sub2package com.carrotsearch.ant.tasks.junit4.tests.sub2; import org.junit.Test; public class TestTwoSeconds { @Test public void oneSecond1() throws Exception { Thread.sleep(1000); } @Test public void oneSecond2() throws Exception { Thread.sleep(1000); } } TestZeroSeconds.java000066400000000000000000000002441235451432000376340ustar00rootroot00000000000000randomizedtesting-release-2.1.6/junit4-ant/src/test/java/com/carrotsearch/ant/tasks/junit4/tests/sub2package com.carrotsearch.ant.tasks.junit4.tests.sub2; import org.junit.Test; public class TestZeroSeconds { @Test public void zero() throws Exception { } } randomizedtesting-release-2.1.6/junit4-ant/src/test/java/proguard/000077500000000000000000000000001235451432000251765ustar00rootroot00000000000000randomizedtesting-release-2.1.6/junit4-ant/src/test/java/proguard/DetectRtJar.java000066400000000000000000000034671235451432000302260ustar00rootroot00000000000000package proguard; import java.io.File; import java.net.JarURLConnection; import java.net.URL; import java.nio.charset.Charset; import java.util.Set; import java.util.TreeSet; import com.google.common.io.Files; public class DetectRtJar { public static void main(String[] args) throws Exception { Set jars = new TreeSet(); Class [] keyClasses = { java.lang.annotation.Annotation.class, java.lang.management.ManagementFactory.class, java.util.logging.Logger.class, java.awt.Component.class, java.beans.BeanDescriptor.class, java.io.File.class, java.lang.Object.class, java.math.BigDecimal.class, java.net.URL.class, java.nio.Buffer.class, java.security.Security.class, java.sql.Array.class, java.text.Collator.class, java.util.List.class, java.util.concurrent.ConcurrentHashMap.class, java.util.zip.ZipEntry.class, org.w3c.dom.Document.class, }; ClassLoader cl = ClassLoader.getSystemClassLoader(); for (Class clazz : keyClasses) { URL url = cl.getResource( clazz.getName().replace('.', '/') + ".class"); if (url.getProtocol().equals("jar")) { JarURLConnection juc = (JarURLConnection) url.openConnection(); jars.add(new File(juc.getJarFile().getName())); } else { // Other scheme? wtf? throw new RuntimeException("Unknown scheme: " + url.toString()); } } StringBuilder b = new StringBuilder(); for (File f : jars) { b.append("-libraryjar ").append(f.getAbsolutePath()); b.append("(java/**)"); b.append("\n"); } System.out.println("Dumping rt.jar path to: " + args[0]); Files.write( b.toString(), new File(args[0]), Charset.defaultCharset()); } } randomizedtesting-release-2.1.6/junit4-ant/src/test/resources/000077500000000000000000000000001235451432000244445ustar00rootroot00000000000000randomizedtesting-release-2.1.6/junit4-ant/src/test/resources/hints-fixed.log000066400000000000000000000005021235451432000273660ustar00rootroot00000000000000com.carrotsearch.ant.tasks.junit4.tests.sub2.TestHalfSecond=500,501,501,501,521 com.carrotsearch.ant.tasks.junit4.tests.sub2.TestOneSecond=1002,1018,1022,1002,1002 com.carrotsearch.ant.tasks.junit4.tests.sub2.TestTwoSeconds=2016,2019,2028,2024,2019 com.carrotsearch.ant.tasks.junit4.tests.sub2.TestZeroSeconds=15,2,1,22,2 randomizedtesting-release-2.1.6/junit4-ant/src/test/resources/junit4.xml000066400000000000000000001265551235451432000264210ustar00rootroot00000000000000 ${native.libs} jvm.exec property must be set. UTF-8 UTF-16 US-ASCII iso8859-1 UTF-8 ${junit4.stats.tests} ${junit4.stats.errors} ${junit4.stats.failures} ${junit4.stats.ignores} ${junit4.stats.suites} ${junit4.stats.assumptions} ${junit4.stats.suiteErrors} ${junit4.stats.nonIgnored} ${junit4.stats.successful} ${junit4.stats.tests} ${junit4.stats.errors} ${junit4.stats.failures} ${junit4.stats.ignores} ${junit4.stats.suites} ${junit4.stats.assumptions} ${junit4.stats.suiteErrors} ${junit4.stats.nonIgnored} ${junit4.stats.successful} randomizedtesting-release-2.1.6/junit4-maven-plugin-tests/000077500000000000000000000000001235451432000236445ustar00rootroot00000000000000randomizedtesting-release-2.1.6/junit4-maven-plugin-tests/pom.xml000066400000000000000000000045401235451432000251640ustar00rootroot00000000000000 4.0.0 com.carrotsearch.randomizedtesting randomizedtesting-parent 2.1.6 ../pom.xml junit4-maven-plugin-tests jar true com.google.guava guava junit junit com.carrotsearch.randomizedtesting randomizedtesting-runner ${project.version} com.carrotsearch.randomizedtesting junit4-maven-plugin ${project.version} maven-invoker-plugin 1.5 true src/it ${project.build.directory}/it true **/pom.xml pom.xml verify ${project.build.directory}/local-repo src/it/settings.xml integration-test install run randomizedtesting-release-2.1.6/junit4-maven-plugin-tests/src/000077500000000000000000000000001235451432000244335ustar00rootroot00000000000000randomizedtesting-release-2.1.6/junit4-maven-plugin-tests/src/it/000077500000000000000000000000001235451432000250475ustar00rootroot00000000000000randomizedtesting-release-2.1.6/junit4-maven-plugin-tests/src/it/01-basic-test/000077500000000000000000000000001235451432000273235ustar00rootroot00000000000000randomizedtesting-release-2.1.6/junit4-maven-plugin-tests/src/it/01-basic-test/invoker.properties000066400000000000000000000000221235451432000331100ustar00rootroot00000000000000invoker.goals=testrandomizedtesting-release-2.1.6/junit4-maven-plugin-tests/src/it/01-basic-test/pom.xml000066400000000000000000000074171235451432000306510ustar00rootroot00000000000000 4.0.0 com.carrotsearch.randomizedtesting junit4-maven-plugin-tests 0.0.1-SNAPSHOT jar 3.0.2 UTF-8 UTF-8 1.6 1.6 com.carrotsearch.randomizedtesting randomizedtesting-runner @project.version@ test org.simpleframework simple-xml 2.6.2 org.apache.maven.plugins maven-compiler-plugin 3.1 org.apache.maven.plugins maven-surefire-plugin true com.carrotsearch.randomizedtesting junit4-maven-plugin @project.version@ junit4-tests junit4 10 pipe,ignore true org.simpleframework:simple-xml -DargLine.property=foobar -DargLine.property2=foobar **/Test0*.class **/Buhu* randomizedtesting-release-2.1.6/junit4-maven-plugin-tests/src/it/01-basic-test/src/000077500000000000000000000000001235451432000301125ustar00rootroot00000000000000randomizedtesting-release-2.1.6/junit4-maven-plugin-tests/src/it/01-basic-test/src/test/000077500000000000000000000000001235451432000310715ustar00rootroot00000000000000randomizedtesting-release-2.1.6/junit4-maven-plugin-tests/src/it/01-basic-test/src/test/java/000077500000000000000000000000001235451432000320125ustar00rootroot00000000000000randomizedtesting-release-2.1.6/junit4-maven-plugin-tests/src/it/01-basic-test/src/test/java/com/000077500000000000000000000000001235451432000325705ustar00rootroot00000000000000000077500000000000000000000000001235451432000351715ustar00rootroot00000000000000randomizedtesting-release-2.1.6/junit4-maven-plugin-tests/src/it/01-basic-test/src/test/java/com/carrotsearch000077500000000000000000000000001235451432000370075ustar00rootroot00000000000000randomizedtesting-release-2.1.6/junit4-maven-plugin-tests/src/it/01-basic-test/src/test/java/com/carrotsearch/examples000077500000000000000000000000001235451432000423755ustar00rootroot00000000000000randomizedtesting-release-2.1.6/junit4-maven-plugin-tests/src/it/01-basic-test/src/test/java/com/carrotsearch/examples/randomizedrunnerTest001InsideMaven.java000066400000000000000000000007301235451432000465230ustar00rootroot00000000000000randomizedtesting-release-2.1.6/junit4-maven-plugin-tests/src/it/01-basic-test/src/test/java/com/carrotsearch/examples/randomizedrunnerpackage com.carrotsearch.examples.randomizedrunner; import org.junit.Assert; import org.junit.Test; public class Test001InsideMaven { @Test public void success() { // Empty. } @Test public void checkArgLinePassed() { Assert.assertEquals("foobar", System.getProperty("argLine.property")); Assert.assertEquals("foobar", System.getProperty("argLine.property2")); Assert.assertEquals("foobar", System.getProperty("verbatim.section")); } } randomizedtesting-release-2.1.6/junit4-maven-plugin-tests/src/it/01-basic-test/verify.bsh000066400000000000000000000006551235451432000313330ustar00rootroot00000000000000 import java.io.*; import java.util.*; import java.util.regex.*; import com.carrotsearch.maven.plugins.junit4.*; la = new LogAssert(new File(basedir, "build.log")); // Tests successful. la.assertLogContains("Tests summary: 1 suite, 2 tests"); // Listener enabled. la.assertLogContains("| Test001InsideMaven.success"); // Assertions. la.assertLogContains("-ea:com.carrotsearch.ant.tasks.junit4.tests.sub1..."); return true; randomizedtesting-release-2.1.6/junit4-maven-plugin-tests/src/it/settings.xml000066400000000000000000000031741235451432000274360ustar00rootroot00000000000000 it-repo true local.central @localRepositoryUrl@ true true local.central @localRepositoryUrl@ true true randomizedtesting-release-2.1.6/junit4-maven-plugin-tests/src/test/000077500000000000000000000000001235451432000254125ustar00rootroot00000000000000randomizedtesting-release-2.1.6/junit4-maven-plugin-tests/src/test/java/000077500000000000000000000000001235451432000263335ustar00rootroot00000000000000randomizedtesting-release-2.1.6/junit4-maven-plugin-tests/src/test/java/com/000077500000000000000000000000001235451432000271115ustar00rootroot00000000000000randomizedtesting-release-2.1.6/junit4-maven-plugin-tests/src/test/java/com/carrotsearch/000077500000000000000000000000001235451432000315715ustar00rootroot00000000000000randomizedtesting-release-2.1.6/junit4-maven-plugin-tests/src/test/java/com/carrotsearch/maven/000077500000000000000000000000001235451432000326775ustar00rootroot00000000000000000077500000000000000000000000001235451432000343015ustar00rootroot00000000000000randomizedtesting-release-2.1.6/junit4-maven-plugin-tests/src/test/java/com/carrotsearch/maven/plugins000077500000000000000000000000001235451432000355165ustar00rootroot00000000000000randomizedtesting-release-2.1.6/junit4-maven-plugin-tests/src/test/java/com/carrotsearch/maven/plugins/junit4LogAssert.java000066400000000000000000000011361235451432000402650ustar00rootroot00000000000000randomizedtesting-release-2.1.6/junit4-maven-plugin-tests/src/test/java/com/carrotsearch/maven/plugins/junit4package com.carrotsearch.maven.plugins.junit4; import java.io.File; import java.io.IOException; import java.nio.charset.Charset; import org.junit.Assert; import com.google.common.io.Files; /** * Asserts on the content of integration tests' log file. */ public class LogAssert { private String logFile; public LogAssert(File buildLog) throws IOException { this.logFile = Files.toString(buildLog, Charset.defaultCharset()); } public void assertLogContains(String text) { Assert.assertTrue("Log file was expected to contain: '" + text + "'", logFile.indexOf(text) >= 0); } } randomizedtesting-release-2.1.6/junit4-maven-plugin/000077500000000000000000000000001235451432000225045ustar00rootroot00000000000000randomizedtesting-release-2.1.6/junit4-maven-plugin/pom.xml000066400000000000000000000067661235451432000240400ustar00rootroot00000000000000 4.0.0 com.carrotsearch.randomizedtesting randomizedtesting-parent 2.1.6 ../pom.xml junit4-maven-plugin maven-plugin com.carrotsearch.randomizedtesting junit4-ant ${project.version} com.carrotsearch.randomizedtesting randomizedtesting-runner ${project.version} true org.apache.maven maven-plugin-api ${minimum.maven.version} org.apache.maven maven-core jar ${minimum.maven.version} org.apache.maven maven-artifact jar ${minimum.maven.version} org.apache.maven maven-compat ${minimum.maven.version} org.apache.ant ant compile org.apache.ant ant-junit compile com.google.guava guava dom4j dom4j org.apache.maven.shared maven-common-artifact-filters 1.4 google-collections com.google.collections maven-project org.apache.maven org.apache.maven.plugins maven-antrun-plugin ${antplugin.version} jar maven-project org.apache.maven org.apache.maven.plugins maven-plugin-plugin generated-helpmojo helpmojo randomizedtesting-release-2.1.6/junit4-maven-plugin/src/000077500000000000000000000000001235451432000232735ustar00rootroot00000000000000randomizedtesting-release-2.1.6/junit4-maven-plugin/src/main/000077500000000000000000000000001235451432000242175ustar00rootroot00000000000000randomizedtesting-release-2.1.6/junit4-maven-plugin/src/main/java/000077500000000000000000000000001235451432000251405ustar00rootroot00000000000000randomizedtesting-release-2.1.6/junit4-maven-plugin/src/main/java/com/000077500000000000000000000000001235451432000257165ustar00rootroot00000000000000randomizedtesting-release-2.1.6/junit4-maven-plugin/src/main/java/com/carrotsearch/000077500000000000000000000000001235451432000303765ustar00rootroot00000000000000randomizedtesting-release-2.1.6/junit4-maven-plugin/src/main/java/com/carrotsearch/maven/000077500000000000000000000000001235451432000315045ustar00rootroot00000000000000randomizedtesting-release-2.1.6/junit4-maven-plugin/src/main/java/com/carrotsearch/maven/plugins/000077500000000000000000000000001235451432000331655ustar00rootroot00000000000000000077500000000000000000000000001235451432000343235ustar00rootroot00000000000000randomizedtesting-release-2.1.6/junit4-maven-plugin/src/main/java/com/carrotsearch/maven/plugins/junit4JUnit4Mojo.java000066400000000000000000000666651235451432000371530ustar00rootroot00000000000000randomizedtesting-release-2.1.6/junit4-maven-plugin/src/main/java/com/carrotsearch/maven/plugins/junit4package com.carrotsearch.maven.plugins.junit4; import java.io.File; import java.io.FileOutputStream; import java.io.IOException; import java.io.OutputStream; import java.io.StringReader; import java.io.StringWriter; import java.util.Arrays; import java.util.Collections; import java.util.List; import java.util.Map; import java.util.Set; import org.apache.maven.artifact.Artifact; import org.apache.maven.artifact.resolver.ArtifactResolutionResult; import org.apache.maven.artifact.resolver.ArtifactResolver; import org.apache.maven.artifact.resolver.filter.ArtifactFilter; import org.apache.maven.artifact.resolver.filter.ExcludesArtifactFilter; import org.apache.maven.artifact.resolver.filter.ScopeArtifactFilter; import org.apache.maven.artifact.versioning.DefaultArtifactVersion; import org.apache.maven.artifact.versioning.InvalidVersionSpecificationException; import org.apache.maven.artifact.versioning.VersionRange; import org.apache.maven.execution.MavenSession; import org.apache.maven.plugin.AbstractMojo; import org.apache.maven.plugin.MojoExecutionException; import org.apache.maven.plugin.MojoFailureException; import org.apache.maven.plugin.antrun.AntrunXmlPlexusConfigurationWriter; import org.apache.maven.project.MavenProject; import org.apache.maven.repository.RepositorySystem; import org.apache.maven.shared.artifact.filter.PatternIncludesArtifactFilter; import org.apache.tools.ant.Project; import org.apache.tools.ant.ProjectHelper; import org.codehaus.plexus.configuration.PlexusConfiguration; import org.dom4j.Document; import org.dom4j.DocumentFactory; import org.dom4j.Element; import org.dom4j.io.OutputFormat; import org.dom4j.io.SAXReader; import org.dom4j.io.XMLWriter; import com.carrotsearch.ant.tasks.junit4.JUnit4; import com.carrotsearch.ant.tasks.junit4.listeners.TextReport; import com.carrotsearch.randomizedtesting.RandomizedRunner; import com.google.common.base.Objects; import com.google.common.base.Strings; import com.google.common.collect.Lists; import com.google.common.collect.Sets; import com.google.common.io.Closer; /** * Run tests using a delegation to Randomized * Testing's JUnit4 ANT task. * * @requiresProject true * @requiresDependencyResolution test * @goal junit4 * @phase test * @threadSafe */ public class JUnit4Mojo extends AbstractMojo { /** An empty String[]. */ private static final String[] EMPTY_STRING_ARRAY = new String [] {}; /** An empty Map. */ private static final Map EMPTY_STRING_STRING_MAP = Collections.emptyMap(); /** Default target in the generated ANT file. */ private static final String DEFAULT_TARGET = "__default__"; /** * The Maven project object * * @parameter property="project" * @readonly */ private MavenProject project; /** * Base directory to invoke slave VMs in. Also note isolateWorkingDirectories * parameter. * * @parameter property="project.build.directory" */ private File dir; /** * The directory to store temporary files in. * * @parameter property="project.build.directory" */ private File tempDir; /** * The number of parallel slaves. Can be set to a constant "max" for the * number of cores returned from {@link Runtime#availableProcessors()} or * "auto" for sensible defaults depending on the number of cores. * The default is a single subprocess. * *

Note that this setting forks physical JVM processes so it multiplies the * requirements for heap memory, IO, etc. * * @parameter default-value="1" */ private String parallelism = JUnit4.DEFAULT_PARALLELISM; /** * Property to set to "true" if there is a failure in a test. The use of this * property is discouraged in Maven (builds should be declarative). * * @parameter */ private String failureProperty; /** * Initial random seed used for shuffling test suites and other sources * of pseudo-randomness. If not set, any random value is set. * *

The seed's format is compatible with {@link RandomizedRunner} so that * seed can be fixed for suites and methods alike. Unless the global prefix of * randomized testing properties is changed, the seed can be overridden using "tests.seed" * property. * * @parameter property="tests.seed" default-value="" */ private String seed; /** * Predictably shuffle tests order after balancing. This will help in spreading * lighter and heavier tests over a single slave's execution timeline while * still keeping the same tests order depending on the seed. * * @parameter default-value="true" */ private boolean shuffleOnSlave = JUnit4.DEFAULT_SHUFFLE_ON_SLAVE; /** * Prints the summary of all executed, ignored etc. tests at the end. * * @parameter default-value="true" */ private boolean printSummary = JUnit4.DEFAULT_PRINT_SUMMARY; /** * Stop the build process if there were failures or errors during test execution. * * @parameter default-value="true" */ private boolean haltOnFailure = JUnit4.DEFAULT_HALT_ON_FAILURE; /** * If set to true each slave JVM gets a separate working directory * under whatever is set in dir. The directory naming for each slave * follows: "Snum", where num is slave's number. Directories are created * automatically and removed unless leaveTemporary is set to * true. * * @parameter default-value="true" */ private boolean isolateWorkingDirectories = JUnit4.DEFAULT_ISOLATE_WORKING_DIRECTORIES; /** * If set to true, any sysout and syserr calls will be written to original * output and error streams (and in effect will appear as "jvm output". By default * sysout and syserrs are captured and proxied to the event stream to be synchronized * with other test events but occasionally one may want to synchronize them with direct * JVM output (to synchronize with compiler output or GC output for example). * * @parameter default-value="false" */ private boolean sysouts = JUnit4.DEFAULT_SYSOUTS; /** * Specifies the ratio of suites moved to dynamic assignment list. A dynamic * assignment list dispatches suites to the first idle slave JVM. Theoretically * this is an optimal strategy, but it is usually better to have some static assignments * to avoid communication costs. * *

A ratio of 0 means only static assignments are used. A ratio of 1 means * only dynamic assignments are used. * *

The list of dynamic assignments is sorted by decreasing cost (always) and * is inherently prone to race conditions in distributing suites. Should there * be an error based on suite-dependency it will not be directly repeatable. In such * case use the per-slave-jvm list of suites file dumped to disk for each slave JVM. * (see leaveTemporary parameter). * * @parameter default-value="0.25" */ private float dynamicAssignmentRatio = JUnit4.DEFAULT_DYNAMIC_ASSIGNMENT_RATIO; /** * Set the maximum memory to be used by all forked JVMs. The value as * defined by -mx or -Xmx in the java * command line options. * * @parameter */ private String maxMemory; /** * Set to true to leave temporary files for diagnostics. * * @parameter */ private boolean leaveTemporary; /** * Add an additional argument to any forked JVM. * * @parameter */ private String [] jvmArgs; /** * Arbitrary JVM options to set on the command line. * * @parameter property="argLine" */ private String argLine; /** * Adds a system property to any forked JVM. * * @parameter */ private Map systemProperties; /** * Adds an environment variable to any forked JVM. * * @parameter */ private Map environmentVariables; /** * The command used to invoke the Java Virtual Machine, default is 'java'. The * command is resolved by java.lang.Runtime.exec(). * * @parameter default-value="java" */ private String jvm; /** * The directory containing generated test classes of the project being * tested. This will be included at the beginning of the test classpath. * * @parameter default-value="${project.build.testOutputDirectory}" */ private File testClassesDirectory; /** * The directory containing generated classes of the project being * tested. This will be included after testClassesDirectory. * * @parameter default-value="${project.build.outputDirectory}" */ private File classesDirectory; /** * A list of <include> elements specifying the tests (by pattern) that should be included in testing. When not * specified defaults to: *

   * <include>**/*Test.class</include>
   * <include>**/Test*.class</include>
   * 
* Note that this may result in nested classes being included for tests. Use proper exclusion patterns. * * @parameter */ private List includes; /** * A list of <exclude> elements specifying the tests (by pattern) that should be excluded in testing. When not * specified defaults to: *
   * <exclude>**/*$*.class</exclude>
   * 
* This patterns excludes any nested classes that might otherwise be included. * * @parameter */ private List excludes; /** * This parameter adds a listener emitting surefire-compatible XMLs if no other listeners * are added. If there are any configured listeners, this parameter is omitted (you can * add a maven-compatible listener manually). * * @parameter default-value="${project.build.directory}/surefire-reports" */ private File surefireReportsDirectory; /** * Specifies the name of the JUnit artifact used for running tests. JUnit dependency * must be in at least version 4.10. * * @parameter property="junitArtifactName" default-value="junit:junit" */ private String junitArtifactName; /** * What should be done on unexpected JVM output? JVM may write directly to the * original descriptors, bypassing redirections of System.out and System.err. Typically, * these messages will be important and should fail the build (permgen space exceeded, * compiler errors, crash dumps). However, certain legitimate logs (gc activity, class loading * logs) are also printed to these streams so sometimes the output can be ignored. * *

Allowed values (any comma-delimited combination of): ignore, pipe, warn, fail. * * @parameter property="jvmOutputAction" default-value="pipe,warn" */ private String jvmOutputAction; /** * Allows or disallow duplicate suite names in resource collections. By default this option * is true because certain ANT-compatible report types (like XML reports) * will have a problem with duplicate suite names (will overwrite files). * * @parameter default-value="true" */ private boolean uniqueSuiteNames = JUnit4.DEFAULT_UNIQUE_SUITE_NAME; /** * Raw listeners configuration. Same XML as for ANT. * * @parameter */ private PlexusConfiguration listeners; /** * Raw assertions configuration. Same XML as for ANT. * * @parameter */ private PlexusConfiguration assertions; /** * Raw balancers configuration. Same XML as for ANT. * * @parameter */ private PlexusConfiguration balancers; /** * Raw section to copy/paste into ANT-driver. * * @parameter */ private PlexusConfiguration verbatim; /** * Sets the heartbeat used to detect inactive/ hung forked tests (JVMs) to the given * number of seconds. The heartbeat detects * no-event intervals and will report them to listeners. Notably, {@link TextReport} report will * emit heartbeat information (to a file or console). * *

Setting the heartbeat to zero means no detection. * * @parameter default-value="0" */ private long heartbeat; /** * Set this to "true" to skip running tests, but still compile them. Its use * is NOT RECOMMENDED, but quite convenient on occasion. * * @parameter default-value="false" property="skipTests" */ private boolean skipTests; /** * List of dependencies to exclude from the test classpath. Each dependency * string must follow the format * groupId:artifactId. For example: org.acme:project-a * *

This is modeled after surefire. An excluded dependency does not mean its * transitive dependencies will also be excluded. * * @parameter */ private List classpathDependencyExcludes; /** * A dependency scope to exclude from the test classpath. The scope can be one of the following scopes: *

*

    *
  • compile - system, provided, compile *
  • runtime - compile, runtime *
  • test - system, provided, compile, runtime, test *
* * @parameter default-value="" */ private String classpathDependencyScopeExclude; /** * Additional elements to be appended to the classpath. * * @parameter */ private List additionalClasspathElements; /** * Map of plugin artifacts. * * @parameter property="plugin.artifactMap" * @required * @readonly */ private Map pluginArtifactMap; /** * Map of project artifacts. * * @parameter property="project.artifactMap" * @required * @readonly */ private Map projectArtifactMap; /** * The current build session instance. * * @parameter property="session" * @required * @readonly */ private MavenSession session; /** * Repository. * * @component * @readonly * @required */ private RepositorySystem repositorySystem; /** * For retrieval of artifact's metadata. * * @component */ @SuppressWarnings("deprecation") private org.apache.maven.artifact.metadata.ArtifactMetadataSource metadataSource; /** * @component */ private ArtifactResolver resolver; /** * Run the mojo. */ @Override public void execute() throws MojoExecutionException, MojoFailureException { validateParameters(); if (skipTests) { return; } // Ant project setup. final Project antProject = new Project(); antProject.init(); antProject.setBaseDir(dir); antProject.addBuildListener(new MavenListenerAdapter(getLog())); // Generate JUnit4 ANT task model and generate a synthetic ANT file. Document doc = DocumentFactory.getInstance().createDocument(); try { populateJUnitElement(createDocumentSkeleton(doc)); File tempAntFile = createTemporaryAntFile(doc); ProjectHelper.configureProject(antProject, tempAntFile); antProject.executeTarget(DEFAULT_TARGET); if (!leaveTemporary) { tempAntFile.delete(); } } catch (IOException e) { throw new MojoExecutionException("An I/O error occurred: " + e.getMessage(), e); } catch (Throwable t) { throw new RuntimeException(t); } } /** * Initial validation of input parameters and configuration. */ private void validateParameters() throws MojoExecutionException { // Check for junit dependency on project level. if (!dir.exists() || !dir.isDirectory()) { throw new MojoExecutionException("Directory does not exist: " + dir.getAbsolutePath()); } // Check for junit dependency on project level. Artifact junitArtifact = projectArtifactMap.get(junitArtifactName); if (junitArtifact == null) { throw new MojoExecutionException("Missing JUnit artifact in project dependencies: " + junitArtifactName); } checkVersion("JUnit", "[4.10,)", junitArtifact); // Fill in complex defaults if not given. if (includes == null || includes.isEmpty()) { includes = Arrays.asList( "**/Test*.class", "**/*Test.class"); } if (excludes == null || excludes.isEmpty()) { excludes = Arrays.asList( "**/*$*.class"); } } /** * Ensure artifactName matches version versionSpec. */ private void checkVersion(String artifactName, String versionSpec, Artifact artifact) throws MojoExecutionException { VersionRange range; try { range = VersionRange.createFromVersionSpec(versionSpec); if (!range.containsVersion(new DefaultArtifactVersion(artifact.getVersion()))) { throw new MojoExecutionException( "JUnit4 plugin requires " + artifactName + " in version " + versionSpec + " among project dependencies, you declared: " + artifact.getVersion()); } } catch (InvalidVersionSpecificationException e) { throw new RuntimeException(e); } } /** * Populate junit4 task with attributes and values. */ private void populateJUnitElement(Element junit4) { // Attributes. if (dir != null) junit4.addAttribute("dir", dir.getAbsolutePath()); if (tempDir != null) junit4.addAttribute("tempDir", tempDir.getAbsolutePath()); if (parallelism != null) junit4.addAttribute("parallelism", parallelism); if (failureProperty != null) junit4.addAttribute("failureProperty", failureProperty); if (seed != null) junit4.addAttribute("seed", seed); if (jvm != null) junit4.addAttribute("jvm", jvm); if (maxMemory != null) junit4.addAttribute("maxMemory", maxMemory); if (jvmOutputAction != null) junit4.addAttribute("jvmOutputAction", jvmOutputAction); if (heartbeat != 0) junit4.addAttribute("heartbeat", Long.toString(heartbeat)); junit4.addAttribute("shuffleOnSlave", Boolean.toString(shuffleOnSlave)); junit4.addAttribute("printSummary", Boolean.toString(printSummary)); junit4.addAttribute("isolateWorkingDirectories", Boolean.toString(isolateWorkingDirectories)); junit4.addAttribute("haltOnFailure", Boolean.toString(haltOnFailure)); junit4.addAttribute("leaveTemporary", Boolean.toString(leaveTemporary)); junit4.addAttribute("dynamicAssignmentRatio", Float.toString(dynamicAssignmentRatio)); junit4.addAttribute("sysouts", Boolean.toString(sysouts)); junit4.addAttribute("uniqueSuiteNames", Boolean.toString(uniqueSuiteNames)); // JVM args. for (String jvmArg : Objects.firstNonNull(jvmArgs, EMPTY_STRING_ARRAY)) { junit4.addElement("jvmarg").addAttribute("value", jvmArg); } if (argLine != null) { junit4.addElement("jvmarg").addAttribute("line", argLine); } // System properties for (Map.Entry e : Objects.firstNonNull(systemProperties, EMPTY_STRING_STRING_MAP).entrySet()) { Element sysproperty = junit4.addElement("sysproperty"); sysproperty.addAttribute("key", Strings.nullToEmpty(e.getKey())); sysproperty.addAttribute("value", Strings.nullToEmpty(e.getValue())); } // Environment variables. for (Map.Entry e : Objects.firstNonNull(environmentVariables, EMPTY_STRING_STRING_MAP).entrySet()) { Element sysproperty = junit4.addElement("env"); sysproperty.addAttribute("key", Strings.nullToEmpty(e.getKey())); sysproperty.addAttribute("value", Strings.nullToEmpty(e.getValue())); } // Tests input. setupTestInput(junit4); // Tests classpath setupTestClasspath(junit4); // Copy over listeners configuration. if (listeners != null) { appendRawXml(listeners, junit4); } else { // Add a console listener and a surefire-like XML listener. Element listenersElement = junit4.addElement("listeners"); Element surefireReport = listenersElement.addElement("report-ant-xml"); surefireReport.addAttribute("dir", surefireReportsDirectory.getAbsolutePath()); surefireReport.addAttribute("mavenExtensions", "true"); Element consoleReport = listenersElement.addElement("report-text"); consoleReport.addAttribute("showThrowable", "true"); consoleReport.addAttribute("showStackTraces", "true"); consoleReport.addAttribute("showOutput", "never"); consoleReport.addAttribute("showStatusOk", "false"); consoleReport.addAttribute("showStatusError", "true"); consoleReport.addAttribute("showStatusFailure", "true"); consoleReport.addAttribute("showStatusIgnored", "false"); consoleReport.addAttribute("showSuiteSummary", "true"); } // Copy over assertions appendRawXml(assertions, junit4); // Copy over balancers appendRawXml(balancers, junit4); // Copy over verbatim section. if (verbatim != null) { for (PlexusConfiguration c : verbatim.getChildren()) { appendRawXml(c, junit4); } } } /** * Append raw XML configuration. */ private void appendRawXml(PlexusConfiguration config, Element elem) { try { if (config == null) { return; } StringWriter writer = new StringWriter(); AntrunXmlPlexusConfigurationWriter xmlWriter = new AntrunXmlPlexusConfigurationWriter(); xmlWriter.write(config, writer); Element root = new SAXReader().read( new StringReader(writer.toString())).getRootElement(); root.detach(); elem.add(root); } catch (Exception e) { throw new RuntimeException(e); } } /** * Create a temporary ANT file for executing JUnit4 ANT task. */ private File createTemporaryAntFile(Document doc) throws IOException { Closer closer = Closer.create(); try { File antFile = File.createTempFile("junit4-ant-", ".xml", dir); OutputStream os = closer.register(new FileOutputStream(antFile)); XMLWriter xmlWriter = new XMLWriter(os, OutputFormat.createPrettyPrint()); xmlWriter.write(doc); return antFile; } catch (Throwable t) { throw closer.rethrow(t); } finally { closer.close(); } } /** * Creates a skeleton of a single-target ANT build file with JUnit4 task inside. */ private Element createDocumentSkeleton(Document doc) { Element project = doc.addElement("project"); project.addAttribute("name", "junit4-maven-synthetic"); project.addAttribute("default", DEFAULT_TARGET); project.addComment("Define JUnit4 task and data types."); Element taskdef = project.addElement("taskdef"); taskdef.addAttribute("resource", JUnit4.ANTLIB_RESOURCE_NAME); addArtifactClassPath( taskdef.addElement("classpath"), pluginArtifactMap.get("com.carrotsearch.randomizedtesting:junit4-ant")); addArtifactClassPath( taskdef.addElement("classpath"), projectArtifactMap.get("junit:junit")); project.addComment("Invoke JUnit4 task."); Element target = project.addElement("target"); target.addAttribute("name", DEFAULT_TARGET); Element junit4 = target.addElement("junit4"); return junit4; } /** * Append classpath elements of the given artefact to classpath. */ private void addArtifactClassPath(Element cp, Artifact artifact) { ArtifactResolutionResult result = resolveArtifact(artifact); if (!result.isSuccess()) { throw new RuntimeException("Could not resolve: " + artifact.toString()); } for (Artifact a : result.getArtifacts()) { cp.addElement("pathelement").addAttribute( "location", a.getFile().getAbsolutePath()); } } /** * Resolve a given artifact given exclusion list. (copied from surefire). */ @SuppressWarnings({"deprecation"}) private ArtifactResolutionResult resolveArtifact(Artifact artifact, Artifact... filtered) { final ArtifactFilter filter; if (filtered.length > 0) { List exclusions = Lists.newArrayListWithExpectedSize(filtered.length); for (Artifact filteredArtifact : filtered) { exclusions.add(filteredArtifact.getGroupId() + ":" + filteredArtifact.getArtifactId()); } filter = new ExcludesArtifactFilter(exclusions); } else { filter = null; } Artifact originatingArtifact = repositorySystem.createArtifact("dummy", "dummy", "1.0", "jar"); try { return resolver.resolveTransitively( Collections.singleton( artifact ), originatingArtifact, session.getLocalRepository(), project.getPluginArtifactRepositories(), metadataSource, filter); } catch (Exception e) { throw new RuntimeException(e); } } /** * Setup the classpath used for tests. */ private void setupTestClasspath(Element junit4) { junit4.addComment("Runtime classpath."); Element cp = junit4.addElement("classpath"); // Test classes. cp.addComment("Test classes directory."); cp.addElement("pathelement").addAttribute("location", testClassesDirectory.getAbsolutePath()); // Classes directory. cp.addComment("Test classes directory."); cp.addElement("pathelement").addAttribute("location", classesDirectory.getAbsolutePath()); // Project dependencies. cp.addComment("Project dependencies."); Set classpathArtifacts = (Set) project.getArtifacts(); if (!Strings.isNullOrEmpty(classpathDependencyScopeExclude)) { classpathArtifacts = filterArtifacts(cp, classpathArtifacts, new ScopeArtifactFilter(classpathDependencyScopeExclude)); } if (classpathDependencyExcludes != null && !classpathDependencyExcludes.isEmpty()) { classpathArtifacts = filterArtifacts(cp, classpathArtifacts, new PatternIncludesArtifactFilter(classpathDependencyExcludes)); } for (Artifact artifact : classpathArtifacts) { if (artifact.getArtifactHandler().isAddedToClasspath()) { File file = artifact.getFile(); if (file != null) { cp.addComment("Dependency artifact: " + artifact.getId()); cp.addElement("pathelement").addAttribute("location", file.getAbsolutePath()); } } } // Additional dependencies. cp.addComment("Additional classpath elements."); if (additionalClasspathElements != null && !additionalClasspathElements.isEmpty()) { for (String classpathElement : additionalClasspathElements) { if (Strings.isNullOrEmpty(classpathElement)) { cp.addElement("pathelement").addAttribute("location", classpathElement); } } } } /** * Return a new set containing only the artifacts accepted by the given filter. */ private Set filterArtifacts(Element cp, Set artifacts, ArtifactFilter filter) { Set filteredArtifacts = Sets.newLinkedHashSet(); for (Artifact artifact : artifacts) { if (!filter.include(artifact)) { filteredArtifacts.add(artifact); } else { cp.addComment("Filtered out artifact: " + artifact.getId() + ", location: " + artifact.getFile()); } } return filteredArtifacts; } /** * Setup the input test suites (classes locations and patterns). */ private void setupTestInput(Element junit4) { Element patternSet = DocumentFactory.getInstance().createElement("patternset"); for (String includePattern : includes) { patternSet.addElement("include").addAttribute("name", includePattern); } for (String excludePattern : excludes) { patternSet.addElement("exclude").addAttribute("name", excludePattern); } if (testClassesDirectory != null) { junit4.addComment("Test classes search paths and patterns."); Element fs = junit4.addElement("fileset"); fs.addAttribute("dir", testClassesDirectory.getAbsolutePath()); fs.add(patternSet.createCopy()); } } } MavenListenerAdapter.java000066400000000000000000000032261235451432000412460ustar00rootroot00000000000000randomizedtesting-release-2.1.6/junit4-maven-plugin/src/main/java/com/carrotsearch/maven/plugins/junit4package com.carrotsearch.maven.plugins.junit4; import org.apache.maven.plugin.logging.Log; import org.apache.tools.ant.*; /** * An adapter to maven logging system from ANT {@link BuildListener}. */ final class MavenListenerAdapter implements BuildListener { private final Log log; public MavenListenerAdapter(Log log) { this.log = log; } @Override public void messageLogged(BuildEvent event) { final Throwable exception = event.getException(); final String message = event.getMessage(); switch (event.getPriority()) { case Project.MSG_DEBUG: case Project.MSG_VERBOSE: if (exception != null) { log.debug(message, exception); } else { log.debug(message); } break; case Project.MSG_INFO: if (exception != null) { log.info(message, exception); } else { log.info(message); } break; case Project.MSG_WARN: if (exception != null) { log.warn(message, exception); } else { log.warn(message); } break; case Project.MSG_ERR: if (exception != null) { log.error(message, exception); } else { log.error(message); } break; } } @Override public void buildFinished(BuildEvent event) {} @Override public void buildStarted(BuildEvent event) {} @Override public void targetFinished(BuildEvent event) {} @Override public void targetStarted(BuildEvent event) {} @Override public void taskFinished(BuildEvent event) {} @Override public void taskStarted(BuildEvent event) {} } randomizedtesting-release-2.1.6/packaging/000077500000000000000000000000001235451432000206135ustar00rootroot00000000000000randomizedtesting-release-2.1.6/packaging/pom.xml000066400000000000000000000062201235451432000221300ustar00rootroot00000000000000 4.0.0 com.carrotsearch.randomizedtesting randomizedtesting-parent 2.1.6 ../pom.xml randomizedtesting-packaging RandomizedTesting Packaging Distribution packaging. true com.carrotsearch.randomizedtesting randomizedtesting-runner ${project.version} compile com.carrotsearch.randomizedtesting randomizedtesting-examples ${project.version} compile com.carrotsearch.randomizedtesting junit4-ant ${project.version} compile release package org.apache.maven.plugins maven-assembly-plugin make-bin package single src/main/assembly/bin.xml false false gnu randomizedtesting-${project.version} make-labs-assembly package single src/main/assembly/site-labs.xml false false site-labs gnu randomizedtesting-release-2.1.6/packaging/src/000077500000000000000000000000001235451432000214025ustar00rootroot00000000000000randomizedtesting-release-2.1.6/packaging/src/main/000077500000000000000000000000001235451432000223265ustar00rootroot00000000000000randomizedtesting-release-2.1.6/packaging/src/main/assembly/000077500000000000000000000000001235451432000241455ustar00rootroot00000000000000randomizedtesting-release-2.1.6/packaging/src/main/assembly/bin.xml000066400000000000000000000051011235451432000254340ustar00rootroot00000000000000 distribution dir tar.gz zip ${project.parent.basedir}/randomized-runner/target lib *.jar *-sources.jar *-javadoc.jar ${project.parent.basedir}/randomized-runner/target/apidocs api/randomizedtesting-runner ${project.parent.basedir}/junit4-ant/src/tasks docs/junit4-ant ${project.parent.basedir}/examples examples **/target/** **/.settings/** **/.classpath/** **/.project/** ant/pom.xml ${project.parent.basedir}/junit4-ant/target lib *.jar *-sources.jar *-javadoc.jar *proguard* ${project.parent.basedir}/junit4-ant/target/dependency lib junit-*.jar ${project.parent.basedir}/junit4-ant/target/apidocs api/junit4-ant ${project.parent.basedir} ./ LICENSE README randomizedtesting-release-2.1.6/packaging/src/main/assembly/site-labs.xml000066400000000000000000000017401235451432000265540ustar00rootroot00000000000000 site-labs false dir ${project.build.directory}/randomizedtesting-${project.version}/randomizedtesting-${project.version} ${project.version}/ api/** docs/** ${project.build.directory} ${project.version}/ *.zip randomizedtesting-release-2.1.6/pom.xml000066400000000000000000000250421235451432000202070ustar00rootroot00000000000000 4.0.0 org.sonatype.oss oss-parent 9 ${minimum.maven.version} com.carrotsearch.randomizedtesting randomizedtesting-parent 2.1.6 pom RandomizedTesting Parent POM http://labs.carrotsearch.com Foundation classes and rules for applying the principles of Randomized Testing. 2011 Carrot Search s.c. http://carrotsearch.com The Apache Software License, Version 2.0 http://www.apache.org/licenses/LICENSE-2.0.txt repo 3.0.2 UTF-8 UTF-8 1.6 1.6 false 4.10 1.7 1.8.2 randomized-runner junit4-ant junit4-maven-plugin junit4-maven-plugin-tests examples/maven examples/ant packaging org.apache.ant ant ${ant.version} org.apache.ant ant-junit ${ant.version} dom4j dom4j 1.6.1 com.google.guava guava 16.0.1 jsr305 com.google.code.findbugs org.ow2.asm asm 5.0_BETA com.google.code.gson gson 2.0 org.simpleframework simple-xml 2.6.2 junit junit ${junit.version} hamcrest-core org.hamcrest org.easytesting fest-assert-core 2.0M6 test commons-io commons-io 2.3 org.apache.maven.plugins maven-javadoc-plugin 2.8.1 http://kentbeck.github.com/junit/javadoc/latest/ ${project.parent.basedir}/etc/javadoc/junit http://guava-libraries.googlecode.com/svn/trunk/javadoc/ ${project.parent.basedir}/etc/javadoc/google-guava org.apache.maven.plugins maven-assembly-plugin 2.2.2 org.apache.maven.plugins maven-source-plugin 2.1.2 org.apache.maven.plugins maven-dependency-plugin 2.3 org.apache.maven.plugins maven-surefire-plugin 2.10 true maven-deploy-plugin ${skip.deployment} org.apache.maven.plugins maven-compiler-plugin 3.1 org.apache.maven.plugins maven-jar-plugin 2.3.2 org.apache.maven.plugins maven-antrun-plugin ${antplugin.version} org.apache.ant ant ${ant.version} org.apache.ant ant-junit ${ant.version} org.apache.maven.plugins maven-plugin-plugin 3.2 java org.eclipse.m2e lifecycle-mapping 1.0.0 org.apache.maven.plugins maven-enforcer-plugin [1.0.0,) enforce quick true true release package org.apache.maven.plugins maven-javadoc-plugin attach-javadocs ${project.build.sourceEncoding} true
${project.name} v${project.version}
API Documentation]]>
${project.name} v${project.version} API Documentation (JavaDoc) ${project.name} v${project.version} API Documentation
${project.name} v${project.version}
API Documentation]]>
true false
jar
org.apache.maven.plugins maven-source-plugin attach-sources jar
randomizedtesting-release-2.1.6/randomized-runner/000077500000000000000000000000001235451432000223325ustar00rootroot00000000000000randomizedtesting-release-2.1.6/randomized-runner/.gitignore000066400000000000000000000000201235451432000243120ustar00rootroot00000000000000/target /target randomizedtesting-release-2.1.6/randomized-runner/README000066400000000000000000000057341235451432000232230ustar00rootroot00000000000000 RandomizedRunner ---------------- RandomizedRunner is a JUnit runner, so it is capable of running @Test-annotated test cases. It respects regular lifecycle hooks such as @Before, @After, @BeforeClass or @AfterClass, but it also adds the following: Randomized, but repeatable execution and infrastructure for dealing with randomness: - uses pseudo-randomness (so that a given run can be repeated if given the same starting seed) for many things called "random" below, - randomly shuffles test methods to ensure they don't depend on each other, - randomly shuffles hooks (within a given class) to ensure they don't depend on each other, - base class RandomizedTest provides a number of methods for generating random numbers, strings and picking random objects from collections (again, this is fully repeatable given the initial seed if there are no race conditions), - the runner provides infrastructure to augment stack traces with information about the initial seeds used for running the test, so that it can be repeated (or it can be determined that the test is not repeatable -- this indicates a problem with the test case itself). Thread control: - any threads created as part of a test case are assigned the same initial random seed (repeatability), - tracks and attempts to terminate any Threads that are created and not terminated inside a test case (not cleaning up causes a test failure), - tracks and attempts to terminate test cases that run for too long (default timeout: 60 seconds, adjustable using global property or annotations), Improved validation and lifecycle support: - RandomizedRunner uses relaxed contracts of hook methods' accessibility (hook methods _can_ be private). This helps in avoiding problems with method shadowing (static hooks) or overrides that require tedious super.() chaining). Private hooks are always executed and don't affect subclasses in any way, period. - @Listeners annotation on a test class allows it to hook into the execution progress and listen to events. - @Validators annotation allows a test class to provide custom validation strategies (project-specific). For example a base class can request specific test case naming strategy (or reject JUnit3-like methods, for instance). - RandomizedRunner does not "chain" or "suppress" exceptions happening during execution of a test case (including hooks). All exceptions are reported as soon as they happened and multiple failure reports can occur. Most environments we know of then display these failures sequentially allowing a clearer understanding of what actually happened first. How to use it? -------------- simple) extend RandomizedTest, (simpler, OR) advanced) annotate your class to use: @With(RandomizedRunner.class) and get RandomizedContext.current() manually. Take a look at the examples and test cases of the runner itself. A video introduction to randomized testing is here: http://vimeo.com/32087114 randomizedtesting-release-2.1.6/randomized-runner/pom.xml000066400000000000000000000113201235451432000236440ustar00rootroot00000000000000 4.0.0 com.carrotsearch.randomizedtesting randomizedtesting-parent 2.1.6 ../pom.xml randomizedtesting-runner RandomizedTesting Randomized Runner junit junit jar compile com.google.guava guava test org.easytesting fest-assert-core test commons-io commons-io test org.apache.maven.plugins maven-javadoc-plugin ${basedir}/src/main/java/com/carrotsearch/randomizedtesting/package.html RandomizedRunner and RandomizedTest com.carrotsearch.randomizedtesting* Annotations com.carrotsearch.randomizedtesting.annotations Listeners, Generators and Validators com.carrotsearch.randomizedtesting.generators:com.carrotsearch.randomizedtesting.listeners:com.carrotsearch.randomizedtesting.validators
${project.name} v${project.version}
API Documentation]]>
org.apache.maven.plugins maven-jar-plugin ${project.build.outputDirectory}/META-INF/MANIFEST.MF org.eclipse.m2e lifecycle-mapping 1.0.0 org.apache.felix maven-bundle-plugin [2.3.4,) manifest
org.apache.felix maven-bundle-plugin 2.3.4 JavaSE-1.6 ${project.groupId}.${project.artifactId} ${project.groupId}.*;version="${project.version}" bundle-manifest process-classes manifest
randomizedtesting-release-2.1.6/randomized-runner/src/000077500000000000000000000000001235451432000231215ustar00rootroot00000000000000randomizedtesting-release-2.1.6/randomized-runner/src/main/000077500000000000000000000000001235451432000240455ustar00rootroot00000000000000randomizedtesting-release-2.1.6/randomized-runner/src/main/java/000077500000000000000000000000001235451432000247665ustar00rootroot00000000000000randomizedtesting-release-2.1.6/randomized-runner/src/main/java/com/000077500000000000000000000000001235451432000255445ustar00rootroot00000000000000randomizedtesting-release-2.1.6/randomized-runner/src/main/java/com/carrotsearch/000077500000000000000000000000001235451432000302245ustar00rootroot00000000000000randomizedtesting-release-2.1.6/randomized-runner/src/main/java/com/carrotsearch/randomizedtesting/000077500000000000000000000000001235451432000337565ustar00rootroot00000000000000AnnotatedMethodProvider.java000066400000000000000000000014301235451432000413310ustar00rootroot00000000000000randomizedtesting-release-2.1.6/randomized-runner/src/main/java/com/carrotsearch/randomizedtestingpackage com.carrotsearch.randomizedtesting; import java.lang.annotation.Annotation; import java.lang.reflect.Method; import java.util.Collection; /** * Base class for {@link TestMethodProvider}s based on annotations. */ public abstract class AnnotatedMethodProvider implements TestMethodProvider { private final Class annotation; public AnnotatedMethodProvider(Class ann) { this.annotation = ann; } @Override public Collection getTestMethods(Class suiteClass, ClassModel suiteClassModel) { // Return all methods annotated with the given annotation. Rely on further validation // to weed out static or otherwise invalid methods. return suiteClassModel.getAnnotatedLeafMethods(annotation).keySet(); } } AssertingRandom.java000066400000000000000000000104641235451432000376470ustar00rootroot00000000000000randomizedtesting-release-2.1.6/randomized-runner/src/main/java/com/carrotsearch/randomizedtestingpackage com.carrotsearch.randomizedtesting; import java.lang.ref.WeakReference; import java.util.Random; /** * A random with a delegate, preventing {@link Random#setSeed(long)} and locked * to be used by a single thread. */ @SuppressWarnings("serial") public final class AssertingRandom extends Random { private final Random delegate; private final WeakReference ownerRef; private final String ownerName; private final StackTraceElement[] allocationStack; /** * Track out-of-context use of this {@link Random} instance. This introduces memory * barriers and scheduling side-effects but there's no other way to do it in any other * way and sharing randoms across threads or test cases is very bad and worth tracking. */ private volatile boolean valid = true; /** * Creates an instance to be used by owner thread and delegating * to delegate until {@link #destroy()}ed. */ public AssertingRandom(Thread owner, Random delegate) { // Must be here, the only Random constructor. Has side-effects on setSeed, see below. super(0); this.delegate = delegate; this.ownerRef = new WeakReference(owner); this.ownerName = owner.toString(); this.allocationStack = Thread.currentThread().getStackTrace(); } @Override protected int next(int bits) { throw new RuntimeException("Shouldn't be reachable."); } @Override public boolean nextBoolean() { checkValid(); return delegate.nextBoolean(); } @Override public void nextBytes(byte[] bytes) { checkValid(); delegate.nextBytes(bytes); } @Override public double nextDouble() { checkValid(); return delegate.nextDouble(); } @Override public float nextFloat() { checkValid(); return delegate.nextFloat(); } @Override public double nextGaussian() { checkValid(); return delegate.nextGaussian(); } @Override public int nextInt() { checkValid(); return delegate.nextInt(); } @Override public int nextInt(int n) { checkValid(); return delegate.nextInt(n); } @Override public long nextLong() { checkValid(); return delegate.nextLong(); } @Override public void setSeed(long seed) { // This is an interesting case of observing uninitialized object from an instance method // (this method is called from the superclass constructor). if (seed == 0 && delegate == null) { return; } throw new RuntimeException( RandomizedRunner.class.getSimpleName() + " prevents changing the seed of its random generators to assure repeatability" + " of tests. If you need a mutable instance of Random, create a new instance," + " preferably with the initial seed aquired from this Random instance."); } @Override public String toString() { checkValid(); return delegate.toString(); } @Override public boolean equals(Object obj) { checkValid(); return delegate.equals(obj); } @Override public int hashCode() { checkValid(); return delegate.hashCode(); } /** * This object will no longer be usable after this method is called. */ public void destroy() { this.valid = false; } /* */ private final void checkValid() { if (!valid) { throw new IllegalStateException("This Random instance has been invalidated and " + "is probably used out of its allowed context (test or suite)."); } final Thread owner = ownerRef.get(); if (owner == null || Thread.currentThread() != owner) { Throwable allocationEx = new StackTraceHolder("Original allocation stack for this Random (" + "allocated by " + ownerName + ")"); allocationEx.setStackTrace(allocationStack); throw new IllegalStateException( "This Random was created for/by another thread (" + ownerName + ")." + " Random instances must not be shared (acquire per-thread). Current thread: " + Thread.currentThread().toString(), allocationEx); } } @Override protected Object clone() throws CloneNotSupportedException { checkValid(); throw new CloneNotSupportedException("Don't clone test Randoms."); } // Overriding this has side effects on the GC; let's not be paranoid. /* protected void finalize() throws Throwable { super.finalize(); } */ } ClassGlobFilter.java000066400000000000000000000010321235451432000375550ustar00rootroot00000000000000randomizedtesting-release-2.1.6/randomized-runner/src/main/java/com/carrotsearch/randomizedtestingpackage com.carrotsearch.randomizedtesting; import org.junit.runner.Description; /** * A filter for {@link Description#getClassName()}. */ public class ClassGlobFilter extends GlobFilter { public ClassGlobFilter(String globPattern) { super(globPattern); } @Override public boolean shouldRun(Description description) { String className = description.getClassName(); return className == null || globMatches(className); } @Override public String describe() { return "Class matches: " + globPattern; } } ClassModel.java000066400000000000000000000213441235451432000365740ustar00rootroot00000000000000randomizedtesting-release-2.1.6/randomized-runner/src/main/java/com/carrotsearch/randomizedtestingpackage com.carrotsearch.randomizedtesting; import java.lang.annotation.Annotation; import java.lang.reflect.Field; import java.lang.reflect.Member; import java.lang.reflect.Method; import java.lang.reflect.Modifier; import java.util.ArrayList; import java.util.Arrays; import java.util.Collections; import java.util.Comparator; import java.util.HashMap; import java.util.Iterator; import java.util.LinkedHashMap; import java.util.List; import java.util.Map; /** * Class model for a test suite. Builds relationship (overrides/ shadows) links * for methods and fields. */ public final class ClassModel { static final Comparator methodSorter = new Comparator() { @Override public int compare(Method o1, Method o2) { return o1.toGenericString().compareTo( o2.toGenericString()); } }; static final Comparator fieldSorter = new Comparator() { @Override public int compare(Field o1, Field o2) { return o1.toGenericString().compareTo( o2.toGenericString()); } }; private final LinkedHashMap methods; private final LinkedHashMap fields; public static enum Scope { PUBLIC, PROTECTED, PACKAGE, PRIVATE } abstract static class ClassElement> { private final int modifiers; private final Scope scope; public final T element; private E up; private E down; public ClassElement(T element) { this.element = element; this.modifiers = element.getModifiers(); this.scope = getAccessScope(modifiers); } private static Scope getAccessScope(int modifiers) { if (Modifier.isPublic(modifiers)) return Scope.PUBLIC; if (Modifier.isProtected(modifiers)) return Scope.PROTECTED; if (Modifier.isPrivate(modifiers)) return Scope.PRIVATE; return Scope.PACKAGE; } void setDown(E down) { assert this.down == null; this.down = down; } void setUp(E up) { assert this.up == null; this.up = up; } public E getDown() { return down; } public E getUp() { return up; } public Scope getAccessScope() { return scope; } abstract boolean overridesOrShadows(ClassElement sub); } private static abstract class ModelBuilder> { final LinkedHashMap build(Class clazz) { final LinkedHashMap elements = new LinkedHashMap(); final Map> tops = new HashMap>(); for (Class c = clazz; c != Object.class; c = c.getSuperclass()) { for (T_MEMBER m : members(c)) { final T_MODEL model = model(m); if (elements.put(m, model) != null) { throw new RuntimeException("Class element should not have duplicates in superclasses: " + m); } // Link up overridden/ shadowed methods to any current tops. if (model.getAccessScope() != Scope.PRIVATE) { List list = tops.get(model); if (list == null) { tops.put(model, list = new ArrayList()); } for (Iterator i = list.iterator(); i.hasNext();) { T_MODEL sub = i.next(); if (model.overridesOrShadows(sub)) { i.remove(); sub.setUp(model); model.setDown(sub); } } list.add(model); } } } return elements; } protected abstract T_MEMBER[] members(Class c); protected abstract T_MODEL model(T_MEMBER t); } public static final class MethodModel extends ClassElement { public MethodModel(Method m) { super(m); } @Override public String toString() { return element.getDeclaringClass().getSimpleName() + "." + element.getName(); } @Override boolean overridesOrShadows(ClassElement sub) { final Method m1 = element; final Method m2 = sub.element; if (!m1.getName().equals(m2.getName())) { return false; } if (!Arrays.equals(m1.getParameterTypes(), m2.getParameterTypes())) { return false; } final Package package1 = m1.getDeclaringClass().getPackage(); final Package package2 = m2.getDeclaringClass().getPackage(); if (getAccessScope() == Scope.PACKAGE) { return package1.equals(package2); } else { return true; } } @Override public int hashCode() { int hashCode = element.getName().hashCode(); for (Class c : element.getParameterTypes()) { hashCode += 31 * c.hashCode(); } return hashCode; } @Override public boolean equals(Object obj) { MethodModel other = (MethodModel) obj; return element.getName().equals(other.element.getName()) && Arrays.equals(element.getParameterTypes(), other.element.getParameterTypes()); } } public static final class FieldModel extends ClassElement { public FieldModel(Field f) { super(f); } @Override public String toString() { return element.getDeclaringClass().getSimpleName() + "." + element.getName(); } @Override boolean overridesOrShadows(ClassElement sub) { final Field f1 = element; final Field f2 = sub.element; if (!f1.getName().equals(f2.getName())) { return false; } final Package package1 = f1.getDeclaringClass().getPackage(); final Package package2 = f1.getDeclaringClass().getPackage(); if (getAccessScope() == Scope.PACKAGE) { return package1.equals(package2); } else { return true; } } @Override public int hashCode() { return element.getName().hashCode(); } @Override public boolean equals(Object obj) { FieldModel other = (FieldModel) obj; return element.getName().equals(other.element.getName()); } } public ClassModel(Class clazz) { methods = methodsModel(clazz); fields = fieldsModel(clazz); } private static LinkedHashMap methodsModel(Class clazz) { return new ModelBuilder() { @Override protected Method [] members(Class c) { Method[] declaredMethods = c.getDeclaredMethods(); Arrays.sort(declaredMethods, methodSorter); return declaredMethods; } @Override protected MethodModel model(Method t) { return new MethodModel(t); } }.build(clazz); } private static LinkedHashMap fieldsModel(Class clazz) { return new ModelBuilder() { @Override protected Field [] members(Class c) { Field[] declaredFields = c.getDeclaredFields(); Arrays.sort(declaredFields, fieldSorter); return declaredFields; } @Override protected FieldModel model(Field t) { return new FieldModel(t); } }.build(clazz); } public Map getMethods() { return Collections.unmodifiableMap(methods); } public Map getFields() { return Collections.unmodifiableMap(fields); } public Map getAnnotatedLeafMethods(final Class annotation) { LinkedHashMap result = new LinkedHashMap(); outer: for (Map.Entry e : getMethods().entrySet()) { MethodModel mm = e.getValue(); if (mm.element.isAnnotationPresent(annotation)) { for (mm = mm.getDown(); mm != null; mm = mm.getDown()) { if (mm.element.isAnnotationPresent(annotation)) { continue outer; } } result.put(e.getKey(), e.getValue()); } } return Collections.unmodifiableMap(result); } public T getAnnotation(Method method, Class annClass, boolean inherited) { MethodModel methodModel = methods.get(method); if (methodModel == null) { throw new IllegalArgumentException("No model for method: " + methodModel); } if (inherited) { for (; methodModel != null; methodModel = methodModel.getUp()) { T annValue = methodModel.element.getAnnotation(annClass); if (annValue != null) { return annValue; } } return null; } else { return method.getAnnotation(annClass); } } public boolean isAnnotationPresent(Method method, Class annClass, boolean inherited) { return getAnnotation(method, annClass, inherited) != null; } } Classes.java000066400000000000000000000005201235451432000361340ustar00rootroot00000000000000randomizedtesting-release-2.1.6/randomized-runner/src/main/java/com/carrotsearch/randomizedtestingpackage com.carrotsearch.randomizedtesting; final class Classes { private Classes() {} public static String simpleName(Class c) { String fullName = c.getName(); int lastDot = fullName.lastIndexOf("."); if (lastDot < 0) { return fullName; } else { return fullName.substring(lastDot + 1); } } } CloseableResourceInfo.java000066400000000000000000000017621235451432000407650ustar00rootroot00000000000000randomizedtesting-release-2.1.6/randomized-runner/src/main/java/com/carrotsearch/randomizedtestingpackage com.carrotsearch.randomizedtesting; import java.io.Closeable; /** * Allocation information (Thread, allocation stack) for tracking disposable * resources. */ final class CloseableResourceInfo { private final Closeable resource; private final LifecycleScope scope; private final StackTraceElement[] allocationStack; private final String threadName; public CloseableResourceInfo(Closeable resource, LifecycleScope scope, Thread t, StackTraceElement[] allocationStack) { this.resource = resource; this.threadName = Threads.threadName(t); this.allocationStack = allocationStack; this.scope = scope; } public Closeable getResource() { return resource; } public StackTraceElement[] getAllocationStack() { return allocationStack; } public LifecycleScope getScope() { return scope; } /** * Return the allocating thread's name at the time of creating this resource info. */ public String getThreadName() { return threadName; } } FilterExpressionParser.java000066400000000000000000000163521235451432000412330ustar00rootroot00000000000000randomizedtesting-release-2.1.6/randomized-runner/src/main/java/com/carrotsearch/randomizedtestingpackage com.carrotsearch.randomizedtesting; import java.util.ArrayList; import java.util.Iterator; import java.util.List; import java.util.Locale; import java.util.regex.Matcher; import java.util.regex.Pattern; /** * Test group conditions filter parser. */ public final class FilterExpressionParser { static final Node [] EMPTY = new Node [0]; @SuppressWarnings("serial") final class SyntaxException extends RuntimeException { final Node node; SyntaxException(Node node, String msg) { super(msg); this.node = node; } @Override public String getMessage() { if (node != null && node.range != null) { return super.getMessage() + " At: \"" + node.range + "\""; } else { return super.getMessage(); } } } interface IContext { boolean defaultValue(); boolean hasGroup(String value); } static class InputRange { final String s; final int start; final int len; InputRange(String value, int start, int length) { this.s = value; this.start = start; this.len = length; } public String value() { return s.substring(start, start + len); } public String toString() { return s.substring(0, start) + ">" + value() + "<" + s.substring(start + len); } } public abstract class Node { int lbp; Node [] args = EMPTY; public InputRange range; Node nud() { throw new SyntaxException(this, "Syntax error."); } Node led(Node left) { throw new SyntaxException(this, "Not an operator."); } @Override public String toString() { return getClass().getSimpleName().replace("Node", ""); } public final String toExpression() { return toExpression(new StringBuilder()).toString(); } protected StringBuilder toExpression(StringBuilder b) { throw new UnsupportedOperationException("Not an expression node: " + toString()); } public boolean evaluate(IContext context) { throw new UnsupportedOperationException("Not an evaluation node: " + toString()); } } class EosNode extends Node { public EosNode() { this.lbp = -1; } } class DefaultNode extends Node { @Override Node nud() { return this; } @Override protected StringBuilder toExpression(StringBuilder b) { b.append("default"); return b; } @Override public boolean evaluate(IContext context) { return context.defaultValue(); } } abstract class InfixNode extends Node { @Override Node led(Node left) { if (!nodes.hasNext()) { throw new SyntaxException(this, "Missing argument for " + toString().toUpperCase(Locale.ENGLISH) + "."); } args = new Node [] {left, expression(lbp)}; return this; } } class AndNode extends InfixNode { public AndNode() { this.lbp = 30; } @Override protected StringBuilder toExpression(StringBuilder b) { assert args.length == 2; b.append("("); b.append(super.args[0].toExpression()); b.append(" AND "); b.append(super.args[1].toExpression()); b.append(")"); return b; } @Override public boolean evaluate(IContext context) { assert args.length == 2; return super.args[0].evaluate(context) && super.args[1].evaluate(context); } } class OrNode extends InfixNode { public OrNode() { this.lbp = 20; } @Override protected StringBuilder toExpression(StringBuilder b) { assert args.length == 2; b.append("("); b.append(super.args[0].toExpression()); b.append(" OR "); b.append(super.args[1].toExpression()); b.append(")"); return b; } @Override public boolean evaluate(IContext context) { assert args.length == 2; return super.args[0].evaluate(context) || super.args[1].evaluate(context); } } class NotNode extends Node { public NotNode() { this.lbp = 40; } @Override Node nud() { args = new Node[] { expression(lbp) }; return this; } @Override protected StringBuilder toExpression(StringBuilder b) { assert args.length == 1; b.append("(NOT "); b.append(super.args[0].toExpression()); b.append(")"); return b; } @Override public boolean evaluate(IContext context) { assert args.length == 1; return !super.args[0].evaluate(context); } } class OpeningBracketNode extends Node { @Override Node nud() { Node expr = expression(0); if (current.getClass() != ClosingBracketNode.class) { throw new SyntaxException(current, "Expected closing bracket."); } current = nodes.next(); return expr; } } class ClosingBracketNode extends Node { @Override Node led(Node left) { throw new SyntaxException(this, "Unbalanced parenthesis."); } } class TestGroupNode extends Node { @Override Node nud() { return this; } @Override protected StringBuilder toExpression(StringBuilder b) { b.append(range.value()); return b; } @Override public boolean evaluate(IContext context) { return context.hasGroup(range.value()); } } private Iterator nodes; private Node current; Node expression(int rbp) { Node n = current; current = nodes.next(); Node left = n.nud(); while (rbp < current.lbp) { n = current; current = nodes.next(); left = n.led(left); } return left; } /** * Pratt's parser. */ public Node parse(String rule) { nodes = tokenize(rule); current = nodes.next(); if (current instanceof EosNode) { return new DefaultNode(); } else { return expression(-1); } } /** * Very simple regexp based tokenizer. We don't need to be fancy or super-fast. */ private Iterator tokenize(String rule) { Matcher m = Pattern.compile( "(?:\\s*)(([^\\s\\(\\)]+)|([\\(\\)]))").matcher(rule); List tokens = new ArrayList(); while (m.find()) { final int s = m.start(1); final int len = m.end(1) - s; final String value = m.group(1); final Node t; if (value.equalsIgnoreCase("DEFAULT")) { t = new DefaultNode(); } else if (value.equals("(")) { t = new OpeningBracketNode(); } else if (value.equals(")")) { t = new ClosingBracketNode(); } else if (value.equalsIgnoreCase("and")) { t = new AndNode(); } else if (value.equalsIgnoreCase("or")) { t = new OrNode(); } else if (value.equalsIgnoreCase("not")) { t = new NotNode(); } else if (value.startsWith("@")) { t = new TestGroupNode(); } else { throw new SyntaxException(null, String.format(Locale.ENGLISH, "Unrecognized token '%s'. At: \"%s\"", value == null ? "" : value, new InputRange(rule, s, len))); } t.range = new InputRange(rule, s, len); tokens.add(t); } Node eos = new EosNode(); eos.range = new InputRange(rule, rule.length(), 0); tokens.add(eos); return tokens.iterator(); } } GlobFilter.java000066400000000000000000000030061235451432000365720ustar00rootroot00000000000000randomizedtesting-release-2.1.6/randomized-runner/src/main/java/com/carrotsearch/randomizedtestingpackage com.carrotsearch.randomizedtesting; import java.util.regex.Pattern; import org.junit.runner.Description; import org.junit.runner.manipulation.Filter; /** * A filter that matches something using globbing (*) pattern. */ public abstract class GlobFilter extends Filter { protected final String globPattern; private final Pattern pattern; public GlobFilter(String glob) { this.globPattern = glob; this.pattern = globToPattern(glob); } /** * Check if a given string matches the glob. */ protected final boolean globMatches(String string) { boolean result = pattern.matcher(string).matches(); return result; } /** * Simplified conversion to a regexp. */ private Pattern globToPattern(String glob) { StringBuilder pattern = new StringBuilder("^"); for (char c : glob.toCharArray()) { switch (c) { case '*': pattern.append(".*"); break; case '?': pattern.append('.'); break; case '.': case '$': case '-': case '{': case '}': case '[': case ']': pattern.append("\\"); pattern.append(c); break; case '\\': pattern.append("\\\\"); break; default: pattern.append(c); } } pattern.append('$'); return Pattern.compile(pattern.toString()); } @Override public abstract boolean shouldRun(Description description); @Override public abstract String describe(); } GroupEvaluator.java000066400000000000000000000123121235451432000375200ustar00rootroot00000000000000randomizedtesting-release-2.1.6/randomized-runner/src/main/java/com/carrotsearch/randomizedtestingpackage com.carrotsearch.randomizedtesting; import java.lang.annotation.Annotation; import java.lang.reflect.AnnotatedElement; import java.util.Arrays; import java.util.HashMap; import java.util.HashSet; import java.util.List; import java.util.Map; import com.carrotsearch.randomizedtesting.FilterExpressionParser.IContext; import com.carrotsearch.randomizedtesting.FilterExpressionParser.Node; import com.carrotsearch.randomizedtesting.RandomizedRunner.TestCandidate; import com.carrotsearch.randomizedtesting.annotations.TestGroup; /** * Evaluates enabled/ disabled state for a given test group. */ class GroupEvaluator { private static class TestGroupInfo { final TestGroup group; final String name; final String sysProperty; final boolean enabled; TestGroupInfo(Class annType) { group = annType.getAnnotation(TestGroup.class); name = TestGroup.Utilities.getGroupName(annType); sysProperty = TestGroup.Utilities.getSysProperty(annType); boolean enabled; try { enabled = RandomizedTest.systemPropertyAsBoolean(sysProperty, group.enabled()); } catch (IllegalArgumentException e) { // Ignore malformed system property, disable the group if malformed though. enabled = false; } this.enabled = enabled; } } private final HashMap, TestGroupInfo> testGroups; private final Node filter; private String filterExpression; GroupEvaluator(List testCandidates) { testGroups = collectGroups(testCandidates); filterExpression = System.getProperty(SysGlobals.SYSPROP_TESTFILTER()); if (filterExpression != null && filterExpression.trim().isEmpty()) { filterExpression = null; } filter = filterExpression != null ? new FilterExpressionParser().parse(filterExpression) : null; } private HashMap, TestGroupInfo> collectGroups(List testCandidates) { final HashMap, TestGroupInfo> groups = new HashMap, TestGroupInfo>(); // Collect all groups declared on methods and instance classes. HashSet> clazzes = new HashSet>(); HashSet annotations = new HashSet(); for (TestCandidate c : testCandidates) { final Class testClass = c.instanceProvider.getTestClass(); if (!clazzes.contains(testClass)) { clazzes.add(testClass); annotations.addAll(Arrays.asList(testClass.getAnnotations())); } annotations.addAll(Arrays.asList(c.method.getAnnotations())); } // Get TestGroup annotated annotations. for (Annotation ann : annotations) { Class annType = ann.annotationType(); if (!groups.containsKey(ann) && annType.isAnnotationPresent(TestGroup.class)) { groups.put(annType, new TestGroupInfo(annType)); } } return groups; } void appendGroupFilteringOptions(ReproduceErrorMessageBuilder builder) { for (TestGroupInfo info : testGroups.values()) { if (System.getProperty(info.sysProperty) != null) { builder.appendOpt(info.sysProperty, System.getProperty(info.sysProperty)); } } if (hasFilteringExpression()) { builder.appendOpt(SysGlobals.SYSPROP_TESTFILTER(), filterExpression); } } public boolean hasFilteringExpression() { return filterExpression != null; } String isTestIgnored(AnnotatedElement... elements) { final Map annotations = new HashMap(); for (AnnotatedElement element : elements) { for (Annotation ann : element.getAnnotations()) { Class annType = ann.annotationType(); if (annType.isAnnotationPresent(TestGroup.class)) { if (!testGroups.containsKey(annType)) { testGroups.put(annType, new TestGroupInfo(annType)); } annotations.put(testGroups.get(annType).name, ann); } } } String defaultState = null; for (Annotation ann : annotations.values()) { TestGroupInfo g = testGroups.get(ann.annotationType()); if (!g.enabled) { defaultState = "'" + g.name + "' test group is disabled (" + toString(ann) + ")"; break; } } if (hasFilteringExpression()) { final String defaultStateCopy = defaultState; boolean enabled = filter.evaluate(new IContext() { @Override public boolean defaultValue() { return defaultStateCopy == null; } @Override public boolean hasGroup(String value) { if (value.startsWith("@")) value = value.substring(1); for (Annotation ann : annotations.values()) { if (value.equalsIgnoreCase(testGroups.get(ann.annotationType()).name)) { return true; } } return false; } }); return enabled ? null : "Test filter condition: " + filterExpression; } else { return defaultState; } } private String toString(Annotation ann) { if (ann == null) return "@null?"; return ann.toString().replace( ann.annotationType().getName(), ann.annotationType().getSimpleName()); } } InstanceProvider.java000066400000000000000000000002641235451432000400230ustar00rootroot00000000000000randomizedtesting-release-2.1.6/randomized-runner/src/main/java/com/carrotsearch/randomizedtestingpackage com.carrotsearch.randomizedtesting; /** * Provide a test instance. */ interface InstanceProvider { Object newInstance() throws Throwable; Class getTestClass(); } InternalAssumptionViolatedException.java000066400000000000000000000024351235451432000437540ustar00rootroot00000000000000randomizedtesting-release-2.1.6/randomized-runner/src/main/java/com/carrotsearch/randomizedtestingpackage com.carrotsearch.randomizedtesting; import org.hamcrest.Description; /** * We have our own "custom" assumption class because of JUnit's internal closed-up architecture. * *

We currently subclass and substitute JUnit's internal AVE, but we could as well have our * own exception and handle it properly in {@link RandomizedRunner}. */ @SuppressWarnings("serial") class InternalAssumptionViolatedException extends org.junit.internal.AssumptionViolatedException { private final String message; public InternalAssumptionViolatedException(String message) { this(message, null); } public InternalAssumptionViolatedException(String message, Throwable t) { super(t, /* no matcher. */ null); if (getCause() != t) { throw new Error("AssumptionViolationException not setting up cause properly. Panic."); } this.message = message; } @Override public String getMessage() { return super.getMessage(); } @Override public void describeTo(Description description) { if (message == null || message.trim().length() == 0) { description.appendText("failed assumption"); } else { description.appendText(message); } if (getCause() != null) { description.appendText("(throwable: " + getCause().toString() + ")"); } } }JUnit3MethodProvider.java000066400000000000000000000014531235451432000405350ustar00rootroot00000000000000randomizedtesting-release-2.1.6/randomized-runner/src/main/java/com/carrotsearch/randomizedtestingpackage com.carrotsearch.randomizedtesting; import java.lang.reflect.Method; import java.util.ArrayList; import java.util.Collection; import java.util.Map; import com.carrotsearch.randomizedtesting.ClassModel.MethodModel; /** * Method provider selecting tests that follow a name pattern of test(.*). */ public class JUnit3MethodProvider implements TestMethodProvider { @Override public Collection getTestMethods(Class suiteClass, ClassModel suiteClassModel) { Map methods = suiteClassModel.getMethods(); ArrayList result = new ArrayList(); for (MethodModel mm : methods.values()) { if (mm.getDown() == null && mm.element.getName().startsWith("test")) { result.add(mm.element); } } return result; } } JUnit4MethodProvider.java000066400000000000000000000004531235451432000405350ustar00rootroot00000000000000randomizedtesting-release-2.1.6/randomized-runner/src/main/java/com/carrotsearch/randomizedtestingpackage com.carrotsearch.randomizedtesting; import org.junit.Test; /** * Method provider selecting {@link Test} annotated public instance parameterless methods. */ public class JUnit4MethodProvider extends AnnotatedMethodProvider { public JUnit4MethodProvider() { super(Test.class); } } LifecycleScope.java000066400000000000000000000005431235451432000374350ustar00rootroot00000000000000randomizedtesting-release-2.1.6/randomized-runner/src/main/java/com/carrotsearch/randomizedtestingpackage com.carrotsearch.randomizedtesting; import org.junit.After; import org.junit.AfterClass; /** * Lifecycle stages for tracking resources. */ public enum LifecycleScope { /** * A single test case, including all {@link After} hooks. */ TEST, /** * A single suite (class), including all {@link AfterClass} hooks. */ SUITE; } MethodGlobFilter.java000066400000000000000000000010441235451432000377330ustar00rootroot00000000000000randomizedtesting-release-2.1.6/randomized-runner/src/main/java/com/carrotsearch/randomizedtestingpackage com.carrotsearch.randomizedtesting; import org.junit.runner.Description; /** * A filter for {@link Description#getMethodName()}. */ public class MethodGlobFilter extends GlobFilter { public MethodGlobFilter(String globPattern) { super(globPattern); } @Override public boolean shouldRun(Description description) { String methodName = description.getMethodName(); return methodName == null || globMatches(methodName); } @Override public String describe() { return "Method matches: " + globPattern; } } MixWithSuiteName.java000066400000000000000000000014121235451432000377440ustar00rootroot00000000000000randomizedtesting-release-2.1.6/randomized-runner/src/main/java/com/carrotsearch/randomizedtestingpackage com.carrotsearch.randomizedtesting; import com.carrotsearch.randomizedtesting.annotations.SeedDecorators; /** * A {@link SeedDecorator} to be used with {@link SeedDecorators} annotation * to modify the master {@link Randomness} with a hash off the suite's class name. */ public class MixWithSuiteName implements SeedDecorator { private long xorHash; @Override public void initialize(Class suiteClass) { this.xorHash = fmix64(suiteClass.getName().hashCode()); } @Override public long decorate(long seed) { return seed ^ xorHash; } /** final mix from murmur hash 3. */ private long fmix64(long k) { k ^= k >>> 33; k *= 0xff51afd7ed558ccdL; k ^= k >>> 33; k *= 0xc4ceb9fe1a85ec53L; k ^= k >>> 33; return k; } }MurmurHash3.java000066400000000000000000000015241235451432000367220ustar00rootroot00000000000000randomizedtesting-release-2.1.6/randomized-runner/src/main/java/com/carrotsearch/randomizedtestingpackage com.carrotsearch.randomizedtesting; /** * Hash routines for primitive types. The implementation is based on the finalization step * from Austin Appleby's MurmurHash3. * * @see "http://sites.google.com/site/murmurhash/" */ final class MurmurHash3 { private MurmurHash3() { // no instances. } /** * Hashes a 4-byte sequence (Java int). */ public static int hash(int k) { k ^= k >>> 16; k *= 0x85ebca6b; k ^= k >>> 13; k *= 0xc2b2ae35; k ^= k >>> 16; return k; } /** * Hashes an 8-byte sequence (Java long). */ public static long hash(long k) { k ^= k >>> 33; k *= 0xff51afd7ed558ccdL; k ^= k >>> 33; k *= 0xc4ceb9fe1a85ec53L; k ^= k >>> 33; return k; } } ObjectProcedure.java000066400000000000000000000001661235451432000376240ustar00rootroot00000000000000randomizedtesting-release-2.1.6/randomized-runner/src/main/java/com/carrotsearch/randomizedtestingpackage com.carrotsearch.randomizedtesting; interface ObjectProcedure { public void apply(KType value); } RandomizedContext.java000066400000000000000000000246611235451432000402140ustar00rootroot00000000000000randomizedtesting-release-2.1.6/randomized-runner/src/main/java/com/carrotsearch/randomizedtestingpackage com.carrotsearch.randomizedtesting; import java.io.Closeable; import java.lang.Thread.State; import java.util.*; import com.carrotsearch.randomizedtesting.annotations.Nightly; import com.carrotsearch.randomizedtesting.annotations.TestGroup; /** * Context variables for an execution of a test suite (hooks and tests) running * under a {@link RandomizedRunner}. */ public final class RandomizedContext { /** Coordination at global level. */ private static final Object _globalLock = new Object(); /** Coordination at context level. */ private final Object _contextLock = new Object(); /** * Per thread assigned resources. */ private final static class PerThreadResources { /** * Generators of pseudo-randomness. This is a queue because we stack * them during lifecycle phases (suite/ method level). */ final ArrayDeque randomnesses = new ArrayDeque(); } /** * All thread groups we're currently tracking contexts for. */ final static IdentityHashMap contexts = new IdentityHashMap(); /** * Per thread resources for each context. Allow GCing of threads. */ final WeakHashMap perThreadResources = new WeakHashMap(); /** A thread group that shares this context. */ private final ThreadGroup threadGroup; /** @see #getTargetClass() */ private final Class suiteClass; /** The runner to which we're bound. */ private final RandomizedRunner runner; /** The context and all of its resources are no longer usable. */ private volatile boolean disposed; /** * Disposable resources. */ private EnumMap> disposableResources = new EnumMap>(LifecycleScope.class); /** * Nightly mode? */ private final boolean nightly; /** */ private RandomizedContext(ThreadGroup tg, Class suiteClass, RandomizedRunner runner) { this.threadGroup = tg; this.suiteClass = suiteClass; this.runner = runner; boolean enabled; try { enabled = RandomizedTest.systemPropertyAsBoolean( TestGroup.Utilities.getSysProperty(Nightly.class), Nightly.class.getAnnotation(TestGroup.class).enabled()); } catch (IllegalArgumentException e) { // Ignore malformed system property, disable the group if malformed though. enabled = false; } this.nightly = enabled; } /** The class (suite) being tested. */ public Class getTargetClass() { checkDisposed(); return suiteClass; } /** Runner's seed. */ long getRunnerSeed() { return runner.runnerRandomness.getSeed(); } /** * Returns the runner's master seed, formatted. */ public String getRunnerSeedAsString() { checkDisposed(); return SeedUtils.formatSeed(getRunnerSeed()); } /** Source of randomness for the context's thread. */ public Randomness getRandomness() { return getPerThread().randomnesses.peekFirst(); } /** * Return all {@link Randomness} on the stack for the current thread. The most * recent (currently used) randomness comes last in this array. */ Randomness [] getRandomnesses() { ArrayDeque randomnesses = getPerThread().randomnesses; Randomness[] array = randomnesses.toArray(new Randomness [randomnesses.size()]); for (int i = 0, j = array.length - 1; i < j; i++, j--) { Randomness r = array[i]; array[i] = array[j]; array[j] = r; } return array; } /** * A shorthand for calling {@link #getRandomness()} and then {@link Randomness#getRandom()}. */ public Random getRandom() { return getRandomness().getRandom(); } /** * Return true if tests are running in nightly mode. */ public boolean isNightly() { checkDisposed(); return nightly; } /** * @return Returns the context for the calling thread or throws an * {@link IllegalStateException} if the thread is out of scope. * @throws IllegalStateException If context is not available. */ public static RandomizedContext current() { return context(Thread.currentThread()); } /** * Access to the runner governing this context. */ public RandomizedRunner getRunner() { return runner; } /** * Dispose the given resource at the end of a given lifecycle scope. If the {@link Closeable} * throws an exception, the test case or suite will end in a failure. * * @return resource (for call chaining). */ public T closeAtEnd(T resource, LifecycleScope scope) { synchronized (_contextLock) { List resources = disposableResources.get(scope); if (resources == null) { disposableResources.put(scope, resources = new ArrayList()); } resources.add(new CloseableResourceInfo( resource, scope, Thread.currentThread(), Thread.currentThread().getStackTrace())); return resource; } } /** * Dispose of any resources registered in the given scope. */ void closeResources(ObjectProcedure consumer, LifecycleScope scope) { List resources; synchronized (_contextLock) { resources = disposableResources.remove(scope); } if (resources != null) { for (CloseableResourceInfo info : resources) { consumer.apply(info); } } } static RandomizedContext context(Thread thread) { ThreadGroup currentGroup = thread.getThreadGroup(); if (currentGroup == null) { throw new IllegalStateException("No context for a terminated thread: " + Threads.threadName(thread)); } synchronized (_globalLock) { RandomizedContext context; while (true) { context = contexts.get(currentGroup); if (context == null && currentGroup.getParent() != null) { currentGroup = currentGroup.getParent(); } else { break; } } if (context == null) { throw new IllegalStateException("No context information for thread: " + Threads.threadName(thread) + ". " + "Is this thread running under a " + RandomizedRunner.class + " runner context? Add @RunWith(" + RandomizedRunner.class + ".class)" + " to your test class. Make sure your code accesses random contexts within " + "@BeforeClass and @AfterClass boundary (for example, static test class initializers are " + "not permitted to access random contexts)."); } synchronized (context._contextLock) { if (!context.perThreadResources.containsKey(thread)) { PerThreadResources perThreadResources = new PerThreadResources(); perThreadResources.randomnesses.push( context.runner.runnerRandomness.clone(thread)); context.perThreadResources.put(thread, perThreadResources); } } return context; } } /** * Create a new context bound to a thread group. */ static RandomizedContext create(ThreadGroup tg, Class suiteClass, RandomizedRunner runner) { assert Thread.currentThread().getThreadGroup() == tg; synchronized (_globalLock) { RandomizedContext ctx = new RandomizedContext(tg, suiteClass, runner); contexts.put(tg, ctx); ctx.perThreadResources.put(Thread.currentThread(), new PerThreadResources()); return ctx; } } /** * Dispose of the context. */ void dispose() { synchronized (_globalLock) { checkDisposed(); disposed = true; contexts.remove(threadGroup); // Clean up and invalidate any per-thread published randoms. synchronized (_contextLock) { for (PerThreadResources ref : perThreadResources.values()) { if (ref != null) { for (Randomness randomness : ref.randomnesses) { randomness.destroy(); } } } } } } /** Push a new randomness on top of the stack. */ void push(Randomness rnd) { getPerThread().randomnesses.push(rnd); } /** Pop a randomness off the stack and dispose it. */ void popAndDestroy() { getPerThread().randomnesses.pop().destroy(); } /** Return per-thread resources associated with the current thread. */ private PerThreadResources getPerThread() { checkDisposed(); synchronized (_contextLock) { return perThreadResources.get(Thread.currentThread()); } } /** * Throw an exception if disposed. */ private void checkDisposed() { if (disposed) { throw new IllegalStateException("Context disposed: " + toString() + " for thread: " + Thread.currentThread()); } } /** * Provide access to {@link GroupEvaluator}. */ public GroupEvaluator getGroupEvaluator() { return runner.groupEvaluator; } /** * Clone context information between the current thread and another thread. * This is for internal use only to propagate context information when forking. */ static void cloneFor(Thread t) { if (t.getState() != State.NEW) { throw new IllegalStateException("The thread to share context with is not in NEW state: " + t); } final ThreadGroup tGroup = t.getThreadGroup(); if (tGroup == null) { throw new IllegalStateException("No thread group for thread: " + t); } Thread me = Thread.currentThread(); if (me.getThreadGroup() != tGroup) { throw new IllegalArgumentException("Both threads must share the thread group."); } synchronized (_globalLock) { RandomizedContext context = contexts.get(tGroup); if (context == null) { throw new IllegalStateException("No context information for thread: " + t); } synchronized (context._contextLock) { if (context.perThreadResources.containsKey(t)) { throw new IllegalStateException("Context already initialized for thread: " + t); } if (!context.perThreadResources.containsKey(me)) { throw new IllegalStateException("Context not initialized for thread: " + me); } PerThreadResources perThreadResources = new PerThreadResources(); for (Randomness r : context.perThreadResources.get(me).randomnesses) { perThreadResources.randomnesses.addLast(r.clone(t)); } context.perThreadResources.put(t, perThreadResources); } } } } RandomizedRunner.java000066400000000000000000001767021235451432000400450ustar00rootroot00000000000000randomizedtesting-release-2.1.6/randomized-runner/src/main/java/com/carrotsearch/randomizedtestingpackage com.carrotsearch.randomizedtesting; import static com.carrotsearch.randomizedtesting.SysGlobals.SYSPROP_APPEND_SEED; import static com.carrotsearch.randomizedtesting.SysGlobals.SYSPROP_ITERATIONS; import static com.carrotsearch.randomizedtesting.SysGlobals.SYSPROP_RANDOM_SEED; import static com.carrotsearch.randomizedtesting.SysGlobals.SYSPROP_STACKFILTERING; import static com.carrotsearch.randomizedtesting.SysGlobals.SYSPROP_TESTCLASS; import static com.carrotsearch.randomizedtesting.SysGlobals.SYSPROP_TESTMETHOD; import java.lang.Thread.UncaughtExceptionHandler; import java.lang.annotation.Annotation; import java.lang.annotation.Inherited; import java.lang.reflect.AnnotatedElement; import java.lang.reflect.Constructor; import java.lang.reflect.InvocationTargetException; import java.lang.reflect.Method; import java.lang.reflect.Modifier; import java.util.ArrayList; import java.util.Arrays; import java.util.Collection; import java.util.Collections; import java.util.Comparator; import java.util.HashMap; import java.util.HashSet; import java.util.IdentityHashMap; import java.util.Iterator; import java.util.LinkedHashMap; import java.util.List; import java.util.Map; import java.util.Random; import java.util.Set; import java.util.concurrent.atomic.AtomicBoolean; import java.util.concurrent.atomic.AtomicLong; import java.util.logging.Level; import java.util.logging.Logger; import java.util.regex.Pattern; import junit.framework.Assert; import org.junit.After; import org.junit.AfterClass; import org.junit.Before; import org.junit.BeforeClass; import org.junit.ClassRule; import org.junit.Ignore; import org.junit.Rule; import org.junit.Test; import org.junit.internal.AssumptionViolatedException; import org.junit.rules.TestRule; import org.junit.runner.Description; import org.junit.runner.Result; import org.junit.runner.Runner; import org.junit.runner.manipulation.Filter; import org.junit.runner.manipulation.Filterable; import org.junit.runner.manipulation.NoTestsRemainException; import org.junit.runner.notification.Failure; import org.junit.runner.notification.RunListener; import org.junit.runner.notification.RunNotifier; import org.junit.runners.model.FrameworkField; import org.junit.runners.model.FrameworkMethod; import org.junit.runners.model.InitializationError; import org.junit.runners.model.MultipleFailureException; import org.junit.runners.model.Statement; import org.junit.runners.model.TestClass; import com.carrotsearch.randomizedtesting.annotations.Listeners; import com.carrotsearch.randomizedtesting.annotations.Name; import com.carrotsearch.randomizedtesting.annotations.ParametersFactory; import com.carrotsearch.randomizedtesting.annotations.Repeat; import com.carrotsearch.randomizedtesting.annotations.Seed; import com.carrotsearch.randomizedtesting.annotations.SeedDecorators; import com.carrotsearch.randomizedtesting.annotations.Seeds; import com.carrotsearch.randomizedtesting.annotations.TestMethodProviders; import com.carrotsearch.randomizedtesting.annotations.ThreadLeakZombies; import com.carrotsearch.randomizedtesting.annotations.Timeout; import com.carrotsearch.randomizedtesting.annotations.TimeoutSuite; import com.carrotsearch.randomizedtesting.rules.StatementAdapter; /** * A {@link Runner} implementation for running randomized test cases with * predictable and repeatable randomness. * *

Supports the following JUnit4 features: *

    *
  • {@link BeforeClass}-annotated methods (before all tests of a class/superclass),
  • *
  • {@link Before}-annotated methods (before each test),
  • *
  • {@link Test}-annotated methods,
  • *
  • {@link After}-annotated methods (after each test),
  • *
  • {@link AfterClass}-annotated methods (after all tests of a class/superclass),
  • *
  • {@link Rule}-annotated fields implementing {@link org.junit.rules.MethodRule} * and {@link TestRule}.
  • *
* *

Contracts: *

    *
  • {@link BeforeClass}, {@link Before} * methods declared in superclasses are called before methods declared in subclasses,
  • *
  • {@link AfterClass}, {@link After} * methods declared in superclasses are called after methods declared in subclasses,
  • *
  • {@link BeforeClass}, {@link Before}, {@link AfterClass}, {@link After} * methods declared within the same class are called in randomized order * derived from the master seed (repeatable with the same seed),
  • *
* *

Deviations from "standard" JUnit: *

    *
  • test methods are allowed to return values (the return value is ignored),
  • *
  • hook methods need not be public; in fact, it is encouraged to make them private to * avoid accidental shadowing which silently drops parent hooks from executing * (applies to class hooks mostly, but also to instance hooks).
  • *
  • all exceptions raised during hooks or test case execution are reported to the notifier, * there is no suppression or chaining of exceptions,
  • *
  • a test method must not leave behind any active threads; this is detected * using {@link ThreadGroup} active counts and is sometimes problematic (many classes * in the standard library leave active threads behind without waiting for them to terminate). * One can use the {@link ThreadLeaks} annotation to control how aggressive the detection * strategy is and if it fails the test or not.
  • *
  • uncaught exceptions from any of children threads will cause the test to fail.
  • *
* * @see RandomizedTest * @see ThreadLeaks * @see Validators * @see Listeners * @see RandomizedContext * @see TestMethodProviders */ @SuppressWarnings("javadoc") public final class RandomizedRunner extends Runner implements Filterable { /** * Fake package of a stack trace entry inserted into exceptions thrown by * test methods. These stack entries contain additional information about * seeds used during execution. */ public static final String AUGMENTED_SEED_PACKAGE = "__randomizedtesting"; /** * Default timeout for a single test case. By default * the timeout is disabled. Use global system property * {@link SysGlobals#SYSPROP_TIMEOUT} or an annotation {@link Timeout} if you need to set * timeouts or expect some test cases may hang. This will slightly slow down * the tests because each test case is executed in a forked thread. * * @see SysGlobals#SYSPROP_TIMEOUT() */ public static final int DEFAULT_TIMEOUT = 0; /** * Default timeout for an entire suite. By default * the timeout is disabled. Use the global system property * {@link SysGlobals#SYSPROP_TIMEOUT_SUITE} or an annotation {@link TimeoutSuite} * if you need to set * timeouts or expect some tests (hooks) may hang. * * @see SysGlobals#SYSPROP_TIMEOUT_SUITE() */ public static final int DEFAULT_TIMEOUT_SUITE = 0; /** * The default number of first interrupts, then Thread.stop attempts. */ public static final int DEFAULT_KILLATTEMPTS = 5; /** * Time in between interrupt retries or stop retries. */ public static final int DEFAULT_KILLWAIT = 500; /** * The default number of test repeat iterations. */ public static final int DEFAULT_ITERATIONS = 1; /** * Test candidate (model). */ static class TestCandidate { public final long seed; public final Description description; public final Method method; public final InstanceProvider instanceProvider; public TestCandidate(Method method, long seed, Description description, InstanceProvider provider) { this.seed = seed; this.description = description; this.method = method; this.instanceProvider = provider; } } /** * Package scope logger. */ final static Logger logger = Logger.getLogger(RandomizedRunner.class.getSimpleName()); /** * A sequencer for affecting the initial seed in case of rapid succession of this class * instance creations. Not likely, but can happen two could get the same seed. */ private final static AtomicLong sequencer = new AtomicLong(); private static final List DEFAULT_STACK_FILTERS = Arrays.asList(new String [] { "org.junit.", "junit.framework.", "sun.", "java.lang.reflect.", "com.carrotsearch.randomizedtesting.", }); /** The class with test methods (suite). */ private final Class suiteClass; /** The runner's seed (master). */ final Randomness runnerRandomness; /** * If {@link #SYSPROP_RANDOM_SEED} property is used with two arguments (master:method) * then this field contains method-level override. */ private Randomness testCaseRandomnessOverride; /** * The number of each test's randomized iterations. * * @see #SYSPROP_ITERATIONS */ private final Integer iterationsOverride; /** All test candidates, processed (seeds assigned) and flattened. */ private List testCandidates; /** Class suite description. */ private Description suiteDescription; /** Applies filters to suite classes. */ private List suiteFilters = new ArrayList(); /** Applies filters to test cases. */ private List testFilters = new ArrayList(); /** * All tests are executed under a specified thread group so that we can have some control * over how many threads have been started/ stopped. System daemons shouldn't be under * this group. */ RunnerThreadGroup runnerThreadGroup; /** * @see #subscribeListeners(RunNotifier) */ private final List autoListeners = new ArrayList(); /** * @see #SYSPROP_APPEND_SEED */ private boolean appendSeedParameter; /** * Stack trace filtering/ dumping. */ private final TraceFormatting traces; /** * The container we're running in. */ private RunnerContainer containerRunner; /** * {@link UncaughtExceptionHandler} for capturing uncaught exceptions * from the test group and globally. */ QueueUncaughtExceptionsHandler handler; /** * Class model. */ private ClassModel classModel; /** * Methods cache. */ private Map,List> shuffledMethodsCache = new HashMap,List>(); /** * A marker for flagging zombie threads (leaked threads that couldn't be killed). */ static AtomicBoolean zombieMarker = new AtomicBoolean(false); /** * The "main" thread group we will be tracking (including subgroups). */ final static ThreadGroup mainThreadGroup = Thread.currentThread().getThreadGroup(); private final Map restoreProperties = new HashMap(); public GroupEvaluator groupEvaluator; /** * What kind of container are we in? Unfortunately we need to adjust * to some "assumptions" containers make about runners. */ private static enum RunnerContainer { ECLIPSE, IDEA, UNKNOWN } /** Creates a new runner for the given class. */ public RandomizedRunner(Class testClass) throws InitializationError { appendSeedParameter = RandomizedTest.systemPropertyAsBoolean(SYSPROP_APPEND_SEED(), false); if (RandomizedTest.systemPropertyAsBoolean(SYSPROP_STACKFILTERING(), true)) { this.traces = new TraceFormatting(DEFAULT_STACK_FILTERS); } else { this.traces = new TraceFormatting(); } this.suiteClass = testClass; this.classModel = new ClassModel(testClass); // Try to detect the container. { this.containerRunner = detectContainer(); } // Initialize the runner's master seed/ randomness source. { List decorators = new ArrayList(); for (SeedDecorators decAnn : getAnnotationsFromClassHierarchy(testClass, SeedDecorators.class)) { for (Class clazz : decAnn.value()) { try { SeedDecorator dec = clazz.newInstance(); dec.initialize(testClass); decorators.add(dec); } catch (Throwable t) { throw new RuntimeException("Could not initialize suite class: " + testClass.getName() + " because its @SeedDecorators contains non-instantiable: " + clazz.getName(), t); } } } SeedDecorator[] decArray = decorators.toArray(new SeedDecorator [decorators.size()]); final long randomSeed = MurmurHash3.hash(sequencer.getAndIncrement() + System.nanoTime()); final String globalSeed = emptyToNull(System.getProperty(SYSPROP_RANDOM_SEED())); final long initialSeed; if (globalSeed != null) { final long[] seedChain = SeedUtils.parseSeedChain(globalSeed); if (seedChain.length == 0 || seedChain.length > 2) { throw new IllegalArgumentException("Invalid system property " + SYSPROP_RANDOM_SEED() + " specification: " + globalSeed); } if (seedChain.length > 1) { testCaseRandomnessOverride = new Randomness(seedChain[1]); } initialSeed = seedChain[0]; } else if (suiteClass.isAnnotationPresent(Seed.class)) { initialSeed = seedFromAnnot(suiteClass, randomSeed)[0]; } else { initialSeed = randomSeed; } runnerRandomness = new Randomness(initialSeed, decArray); } // Iterations property is primary wrt to annotations, so we leave an "undefined" value as null. if (emptyToNull(System.getProperty(SYSPROP_ITERATIONS())) != null) { this.iterationsOverride = RandomizedTest.systemPropertyAsInt(SYSPROP_ITERATIONS(), 0); if (iterationsOverride < 1) throw new IllegalArgumentException( "System property " + SYSPROP_ITERATIONS() + " must be >= 1: " + iterationsOverride); } else { this.iterationsOverride = null; } try { // Fail fast if suiteClass is inconsistent or selected "standard" JUnit rules are somehow broken. validateTarget(); // Collect all test candidates, regardless if they will be executed or not. suiteDescription = Description.createSuiteDescription(suiteClass); testCandidates = collectTestCandidates(suiteDescription); this.groupEvaluator = new GroupEvaluator(testCandidates); } catch (Throwable t) { throw new InitializationError(t); } } /** * Attempt to detect the container we're running under. */ private static RunnerContainer detectContainer() { StackTraceElement [] stack = Thread.currentThread().getStackTrace(); // Look for Eclipse first. if (stack.length > 0) { String topClass = stack[stack.length - 1].getClassName(); if (topClass.equals("org.eclipse.jdt.internal.junit.runner.RemoteTestRunner")) { return RunnerContainer.ECLIPSE; } if (topClass.startsWith("com.intellij.")) { return RunnerContainer.IDEA; } } return RunnerContainer.UNKNOWN; } /** * Return the current tree of test descriptions (filtered). */ @Override public Description getDescription() { return suiteDescription; } /** * Implement {@link Filterable} because GUIs depend on it to run tests selectively. */ @Override public void filter(Filter filter) throws NoTestsRemainException { this.testFilters.add(filter); } /** * Runs all tests and hooks. */ @Override public void run(RunNotifier notifier) { processSystemProperties(); try { runSuite(notifier); } finally { restoreSystemProperties(); } } private void restoreSystemProperties() { for (Map.Entry e : restoreProperties.entrySet()) { if (e.getValue() == null) { System.clearProperty(e.getKey()); } else { System.setProperty(e.getKey(), e.getValue()); } } } private void processSystemProperties() { if (emptyToNull(System.getProperty(SYSPROP_TESTCLASS())) != null) { suiteFilters.add(new ClassGlobFilter(System.getProperty(SYSPROP_TESTCLASS()))); } if (emptyToNull(System.getProperty(SYSPROP_TESTMETHOD())) != null) { testFilters.add(new MethodGlobFilter(System.getProperty(SYSPROP_TESTMETHOD()))); } if (emptyToNull(System.getProperty(SysGlobals.CHILDVM_SYSPROP_JVM_COUNT)) == null && emptyToNull(System.getProperty(SysGlobals.CHILDVM_SYSPROP_JVM_ID)) == null) { // We don't run under JUnit4 so we have to fill in these manually. restoreProperties.put(SysGlobals.CHILDVM_SYSPROP_JVM_COUNT, System.getProperty(SysGlobals.CHILDVM_SYSPROP_JVM_COUNT)); restoreProperties.put(SysGlobals.CHILDVM_SYSPROP_JVM_ID, System.getProperty(SysGlobals.CHILDVM_SYSPROP_JVM_ID)); System.setProperty(SysGlobals.CHILDVM_SYSPROP_JVM_COUNT, "1"); System.setProperty(SysGlobals.CHILDVM_SYSPROP_JVM_ID, "0"); } } static class UncaughtException { final Thread thread; final String threadName; final Throwable error; UncaughtException(Thread t, Throwable error) { this.threadName = Threads.threadName(t); this.thread = t; this.error = error; } } /** * Queue uncaught exceptions. */ static class QueueUncaughtExceptionsHandler implements UncaughtExceptionHandler { private final ArrayList uncaughtExceptions = new ArrayList(); private boolean reporting = true; @Override public void uncaughtException(Thread t, Throwable e) { synchronized (this) { if (!reporting) { return; } uncaughtExceptions.add(new UncaughtException(t, e)); } Logger.getLogger(RunnerThreadGroup.class.getSimpleName()).log( Level.WARNING, "Uncaught exception in thread: " + t, e); } /** * Stop reporting uncaught exceptions. */ void stopReporting() { synchronized (this) { reporting = false; } } /** * Resume uncaught exception reporting. */ void resumeReporting() { synchronized (this) { reporting = true; } } /** * Return the current list of uncaught exceptions and clear it. */ public List getUncaughtAndClear() { synchronized (this) { final ArrayList copy = new ArrayList(uncaughtExceptions); uncaughtExceptions.clear(); return copy; } } } /** * Test execution logic for the entire suite. */ private void runSuite(final RunNotifier notifier) { // TODO: this effectively means we can't run concurrent randomized runners. final UncaughtExceptionHandler previous = Thread.getDefaultUncaughtExceptionHandler(); handler = new QueueUncaughtExceptionsHandler(); Thread.setDefaultUncaughtExceptionHandler(handler); this.runnerThreadGroup = new RunnerThreadGroup( "TGRP-" + Classes.simpleName(suiteClass)); final Thread runner = new Thread(runnerThreadGroup, "SUITE-" + Classes.simpleName(suiteClass) + "-seed#" + SeedUtils.formatSeedChain(runnerRandomness)) { public void run() { try { // Make sure static initializers are invoked and that they are invoked outside of // the randomized context scope. This is for consistency so that we're not relying // on the class NOT being initialized before. try { Class.forName(suiteClass.getName(), true, suiteClass.getClassLoader()); } catch (ExceptionInInitializerError e) { throw e.getCause(); } RandomizedContext context = createContext(runnerThreadGroup); runSuite(context, notifier); context.dispose(); } catch (Throwable t) { notifier.fireTestFailure(new Failure(suiteDescription, t)); } } }; runner.start(); try { runner.join(); } catch (InterruptedException e) { notifier.fireTestFailure(new Failure(suiteDescription, new RuntimeException("Interrupted while waiting for the suite runner? Weird.", e))); } if (Thread.getDefaultUncaughtExceptionHandler() != handler) { notifier.fireTestFailure(new Failure(suiteDescription, new RuntimeException("Suite replaced Thread.defaultUncaughtExceptionHandler. " + "It's better not to touch it. Or at least revert it to what it was before. Current: " + Thread.getDefaultUncaughtExceptionHandler().getClass()))); } Thread.setDefaultUncaughtExceptionHandler(previous); runnerThreadGroup = null; handler = null; } /** * Test execution logic for the entire suite, executing under designated * {@link RunnerThreadGroup}. */ private void runSuite(final RandomizedContext context, final RunNotifier notifier) { final Result result = new Result(); final RunListener accounting = result.createListener(); notifier.addListener(accounting); final Randomness classRandomness = runnerRandomness.clone(Thread.currentThread()); context.push(classRandomness); try { // Check for automatically hookable listeners. subscribeListeners(notifier); // Fire a synthetic "suite started" event. for (RunListener r : autoListeners) { try { r.testRunStarted(suiteDescription); } catch (Throwable e) { logger.log(Level.SEVERE, "Panic: RunListener hook shouldn't throw exceptions.", e); } } // Filter out test candidates to see if there's anything left. If not, // don't bother running class hooks. final List filtered = getFilteredTestCandidates(); // Filter out any tests ignored by filtering expression final GroupEvaluator evaluator = RandomizedContext.current().getGroupEvaluator(); if (evaluator.hasFilteringExpression()) { for (Iterator i = filtered.iterator(); i.hasNext();) { TestCandidate c = i.next(); if (evaluator.isTestIgnored(c.method, suiteClass) != null) { i.remove(); } } } if (!filtered.isEmpty()) { if (areAllRemainingIgnored(filtered)) { for (TestCandidate candidate : filtered) { if (!isTestIgnored(notifier, candidate)) { throw new RuntimeException("Should not reach here."); } } } else { ThreadLeakControl threadLeakControl = new ThreadLeakControl(notifier, this); Statement s = runTestsStatement(threadLeakControl.notifier(), filtered, threadLeakControl); s = withClassBefores(s); s = withClassAfters(s); s = withClassRules(s); s = withCloseContextResources(s, LifecycleScope.SUITE); s = threadLeakControl.forSuite(s, suiteDescription); try { s.evaluate(); } catch (Throwable t) { t = augmentStackTrace(t, runnerRandomness); if (t instanceof AssumptionViolatedException) { // Fire assumption failure before method ignores. (GH-103). notifier.fireTestAssumptionFailed(new Failure(suiteDescription, t)); // Class level assumptions cause all tests to be ignored. // see Rants#RANT_3 for (final TestCandidate c : filtered) { notifier.fireTestIgnored(c.description); } } else { fireTestFailure(notifier, suiteDescription, t); } } } } } catch (Throwable t) { notifier.fireTestFailure(new Failure(suiteDescription, t)); } // Fire a synthetic "suite ended" event and unsubscribe listeners. for (RunListener r : autoListeners) { try { r.testRunFinished(result); } catch (Throwable e) { logger.log(Level.SEVERE, "Panic: RunListener hook shouldn't throw exceptions.", e); } } // Final cleanup. notifier.removeListener(accounting); unsubscribeListeners(notifier); context.popAndDestroy(); } private boolean areAllRemainingIgnored(List filtered) { RunNotifier fake = new RunNotifier(); for (TestCandidate candidate : filtered) { if (!isTestIgnored(fake, candidate)) { return false; } } return true; } /** * Wrap with a rule to close context resources. */ private static Statement withCloseContextResources(final Statement s, final LifecycleScope scope) { return new StatementAdapter(s) { @Override protected void afterAlways(final List errors) throws Throwable { final ObjectProcedure disposer = new ObjectProcedure() { public void apply(CloseableResourceInfo info) { try { info.getResource().close(); } catch (Throwable t) { ResourceDisposalError e = new ResourceDisposalError( "Resource in scope " + info.getScope().name() + " failed to close. Resource was" + " registered from thread " + info.getThreadName() + ", registration stack trace below.", t); e.setStackTrace(info.getAllocationStack()); errors.add(e); } } }; RandomizedContext.current().closeResources(disposer, scope); } }; } private Statement runTestsStatement( final RunNotifier notifier, final List filtered, final ThreadLeakControl threadLeakControl) { return new Statement() { public void evaluate() throws Throwable { for (final TestCandidate c : filtered) { if (isTestIgnored(notifier, c)) { continue; } // Run the test. final String testThreadName = "TEST-" + Classes.simpleName(suiteClass) + "." + c.method.getName() + "-seed#" + SeedUtils.formatSeedChain(runnerRandomness); // This has a side effect of setting up a nested context for the test thread. final String restoreName = Thread.currentThread().getName(); final RandomizedContext current = RandomizedContext.current(); try { Thread.currentThread().setName(testThreadName); current.push(new Randomness(c.seed)); runSingleTest(notifier, c, threadLeakControl); } finally { Thread.currentThread().setName(restoreName); current.popAndDestroy(); } } } }; } private void fireTestFailure(RunNotifier notifier, Description description, Throwable t) { if (t instanceof MultipleFailureException) { for (Throwable nested : ((MultipleFailureException) t).getFailures()) { fireTestFailure(notifier, description, nested); } } else { notifier.fireTestFailure(new Failure(description, t)); } } /** * Decorate a {@link Statement} with {@link BeforeClass} hooks. */ private Statement withClassBefores(final Statement s) { return new Statement() { @Override public void evaluate() throws Throwable { try { for (Method method : getShuffledMethods(BeforeClass.class)) { invoke(method, null); } } catch (Throwable t) { throw augmentStackTrace(t, runnerRandomness); } s.evaluate(); } }; } private Statement withClassAfters(final Statement s) { return new Statement() { @Override public void evaluate() throws Throwable { List errors = new ArrayList(); try { s.evaluate(); } catch (Throwable t) { errors.add(augmentStackTrace(t, runnerRandomness)); } for (Method method : getShuffledMethods(AfterClass.class)) { try { invoke(method, null); } catch (Throwable t) { errors.add(augmentStackTrace(t, runnerRandomness)); } } MultipleFailureException.assertEmpty(errors); } }; } /** * Wrap with {@link ClassRule}s. */ private Statement withClassRules(Statement s) { List classRules = getAnnotatedFieldValues(null, ClassRule.class, TestRule.class); for (TestRule rule : classRules) { s = rule.apply(s, suiteDescription); } return s; } /** * Runs a single test in the "master" test thread. */ void runSingleTest(final RunNotifier notifier, final TestCandidate c, final ThreadLeakControl threadLeakControl) { notifier.fireTestStarted(c.description); final Object instance; try { // Get the test instance. instance = c.instanceProvider.newInstance(); // Collect rules and execute wrapped method. Statement s = new Statement() { public void evaluate() throws Throwable { invoke(c.method, instance); } }; s = wrapExpectedExceptions(s, c); s = wrapBeforeAndAfters(s, c, instance); s = wrapMethodRules(s, c, instance); s = withCloseContextResources(s, LifecycleScope.TEST); s = threadLeakControl.forTest(s, c); s.evaluate(); } catch (Throwable e) { e = augmentStackTrace(e); if (e instanceof AssumptionViolatedException) { notifier.fireTestAssumptionFailed(new Failure(c.description, e)); } else { fireTestFailure(notifier, c.description, e); } } finally { notifier.fireTestFinished(c.description); } } /** * Wrap before and after hooks. */ private Statement wrapBeforeAndAfters(Statement s, final TestCandidate c, final Object instance) { // Process @Before hooks. The first @Before to fail will immediately stop processing any other @Befores. final List befores = getShuffledMethods(Before.class); if (!befores.isEmpty()) { final Statement afterBefores = s; s = new Statement() { @Override public void evaluate() throws Throwable { for (Method m : befores) { invoke(m, instance); } afterBefores.evaluate(); } }; } // Process @After hooks. All @After hooks are processed, regardless of their own exceptions. final List afters = getShuffledMethods(After.class); if (!afters.isEmpty()) { final Statement afterAfters = s; s = new Statement() { @Override public void evaluate() throws Throwable { List cumulative = new ArrayList(); try { afterAfters.evaluate(); } catch (Throwable t) { cumulative.add(t); } // All @Afters must be called. for (Method m : afters) { try { invoke(m, instance); } catch (Throwable t) { cumulative.add(t); } } // At end, throw the exception or cumulate. // // TODO: this is unfortunate, but we need to propagate exceptions up the stack because // certain rules may choose to... ignore exceptions that happened on the @After hooks. // it really should be a requirement that hook methods do _not_ throw any excepions // and if they do (unchecked), these should be propagated to the notifier and not up // the stack (where they can be ignored or obscured). if (cumulative.size() == 1) { throw cumulative.get(0); } if (cumulative.size() > 1) { throw new MultipleFailureException(cumulative); } } }; } return s; } /** * Wrap the given statement into another catching the expected exception, if declared. */ private Statement wrapExpectedExceptions(final Statement s, TestCandidate c) { Test ann = c.method.getAnnotation(Test.class); if (ann == null) { return s; } // If there's no expected class, don't wrap. Eh, None is package-private... final Class expectedClass = ann.expected(); if (expectedClass.getName().equals("org.junit.Test$None")) { return s; } return new Statement() { @Override public void evaluate() throws Throwable { try { s.evaluate(); } catch (Throwable t) { if (!expectedClass.isInstance(t)) { throw t; } // We caught something that was expected. No worries then. return; } // If we're here this means we passed the test that expected a failure. Assert.fail("Expected an exception but the test passed: " + expectedClass.getName()); } }; } /** * Wrap the given statement in any declared MethodRules (old style rules). */ @SuppressWarnings("deprecation") private Statement wrapMethodRules(Statement s, TestCandidate c, Object instance) { FrameworkMethod fm = new FrameworkMethod(c.method); // Old-style MethodRules first. List methodRules = getAnnotatedFieldValues(instance, Rule.class, org.junit.rules.MethodRule.class); for (org.junit.rules.MethodRule rule : methodRules) { s = rule.apply(s, fm, instance); } // New-style TestRule next. List testRules = getAnnotatedFieldValues(instance, Rule.class, TestRule.class); for (TestRule rule : testRules) { s = rule.apply(s, c.description); } return s; } /* * We're using JUnit infrastructure here, but provide constant * ordering of the result. The returned list has class...super order. */ private List getAnnotatedFieldValues(Object test, Class annotationClass, Class valueClass) { TestClass info = new TestClass(suiteClass); List results = new ArrayList(); List annotatedFields = new ArrayList(info.getAnnotatedFields(annotationClass)); // Split fields by class final HashMap, List> byClass = new HashMap, List>(); for (FrameworkField field : annotatedFields) { Class clz = field.getField().getDeclaringClass(); if (!byClass.containsKey(clz)) { byClass.put(clz, new ArrayList()); } byClass.get(clz).add(field); } // Consistent order at class level. for (List fields : byClass.values()) { Collections.sort(fields, new Comparator() { @Override public int compare(FrameworkField o1, FrameworkField o2) { return o1.getField().getName().compareTo( o2.getField().getName()); } }); Collections.shuffle(fields, new Random(runnerRandomness.getSeed())); } annotatedFields.clear(); for (Class clz = suiteClass; clz != null; clz = clz.getSuperclass()) { List clzFields = byClass.get(clz); if (clzFields != null) { annotatedFields.addAll(clzFields); } } for (FrameworkField each : annotatedFields) { try { Object fieldValue = each.get(test); if (valueClass.isInstance(fieldValue)) results.add(valueClass.cast(fieldValue)); } catch (IllegalAccessException e) { throw new RuntimeException(e); } } return results; } /** * Create randomized context for the run. The context is shared by all * threads in a given thread group (but the source of {@link Randomness} * is assigned per-thread). */ private RandomizedContext createContext(ThreadGroup tg) { return RandomizedContext.create(tg, suiteClass, this); } /** Subscribe annotation listeners to the notifier. */ private void subscribeListeners(RunNotifier notifier) { for (Listeners ann : getAnnotationsFromClassHierarchy(suiteClass, Listeners.class)) { for (Class clazz : ann.value()) { try { RunListener listener = clazz.newInstance(); autoListeners.add(listener); notifier.addListener(listener); } catch (Throwable t) { throw new RuntimeException("Could not initialize suite class: " + suiteClass.getName() + " because its @Listener is not instantiable: " + clazz.getName(), t); } } } } /** Unsubscribe listeners. */ private void unsubscribeListeners(RunNotifier notifier) { for (RunListener r : autoListeners) notifier.removeListener(r); } /** * Apply filtering to candidates. */ private List getFilteredTestCandidates() { // Apply suite filters. if (!suiteFilters.isEmpty()) { for (Filter f : suiteFilters) { if (!f.shouldRun(suiteDescription)) { return Collections.emptyList(); } } } // Apply method filters. if (testFilters.isEmpty()) { return testCandidates; } final List filtered = new ArrayList(testCandidates); for (Iterator i = filtered.iterator(); i.hasNext(); ) { final TestCandidate candidate = i.next(); for (Filter f : testFilters) { // Inquire for both full description (possibly with parameters and seed) // and simplified description (just method name). if (f.shouldRun(candidate.description) || f.shouldRun(Description.createTestDescription( candidate.instanceProvider.getTestClass(), candidate.method.getName()))) { continue; } i.remove(); break; } } // GH-89. if (testCandidates.size() > 0 && filtered.isEmpty()) { final boolean expandedCandidates = candidatesWithRandomSeeds(testCandidates); final boolean filtersIncludeSeed = filtersIncludeSeed(testFilters); if (expandedCandidates && filtersIncludeSeed) { Logger.getAnonymousLogger().warning( "Empty set of tests for suite class " + suiteClass.getSimpleName() + " after filters applied. This can be caused by an attempt to filter tests with a random" + " or fixed seed different than the filter's. Use the same constant seed " + "(-Dtests.seed=deadbeef) to get a reproducible (and filterable)" + " set of tests."); } if (expandedCandidates && !filtersIncludeSeed) { String warningMessage = "Empty set of tests for suite class " + suiteClass.getSimpleName() + " after filters applied."; if (emptyToNull(System.getProperty(SYSPROP_TESTMETHOD())) != null) { warningMessage += " Your method filter property should be a glob pattern to cater for" + " the random seed appended to each expanded test repetition. Use -D" + SysGlobals.SYSPROP_TESTMETHOD() + "=" + System.getProperty(SYSPROP_TESTMETHOD()) + "*"; } else { warningMessage += " This can be caused by an attempt to filter tests by fixed method name" + " when their repetitions are expanded with a random seed to make their names unique. Use" + " a globbing pattern in your filters to ignore anything after the method name, for example:" + " -D" + SysGlobals.SYSPROP_TESTMETHOD() + "=method*"; } Logger.getAnonymousLogger().warning(warningMessage); } } return filtered; } /** * Check if any of the filters includes a description that would suggest it's looking * for a filter with seed. */ private boolean filtersIncludeSeed(List filters) { for (Filter f : filters) { if (hasSeedPattern(f.describe())) return true; } return false; } /** * Check if this string has a pattern of containing seed. */ private boolean hasSeedPattern(String description) { Pattern p = Pattern.compile("seed=\\["); return p.matcher(description).find(); } /** * Check if the set of test candidates contains tests with seeds. */ private boolean candidatesWithRandomSeeds(List testCandidates) { for (TestCandidate tc : testCandidates) { if (hasSeedPattern(tc.description.getMethodName())) { return true; } } return false; } /** * Normalize empty strings to nulls. */ static String emptyToNull(String value) { if (value == null || value.trim().isEmpty()) return null; return value.trim(); } /** * Returns true if we should ignore this test candidate. */ private boolean isTestIgnored(RunNotifier notifier, TestCandidate c) { // Check for @Ignore on method early on, like JUnit. if (c.method.getAnnotation(Ignore.class) != null) { notifier.fireTestIgnored(c.description); return true; } final GroupEvaluator evaluator = RandomizedContext.current().getGroupEvaluator(); String reasonIgnored = evaluator.isTestIgnored(c.method, suiteClass); if (reasonIgnored != null) { /* * This is mighty weird but it's a workaround for JUnit's limitations in passing the * cause of an ignored test and at the same time mark a test as ignored in certain IDEs * (Eclipse). */ notifier.fireTestStarted(c.description); if (containerRunner != RunnerContainer.IDEA) { notifier.fireTestIgnored(c.description); } notifier.fireTestAssumptionFailed(new Failure(c.description, new InternalAssumptionViolatedException(reasonIgnored))); notifier.fireTestFinished(c.description); return true; } return false; } /** * Construct a list of ordered framework methods. Minor tweaks are done depending * on the annotation (reversing order, etc.). */ private List getShuffledMethods(Class ann) { List methods = shuffledMethodsCache.get(ann); if (methods != null) { return methods; } methods = new ArrayList(classModel.getAnnotatedLeafMethods(ann).keySet()); // Shuffle sub-ranges using class level randomness. Random rnd = new Random(runnerRandomness.getSeed()); for (int i = 0, j = 0; i < methods.size(); i = j) { final Method m = methods.get(i); j = i + 1; while (j < methods.size() && m.getDeclaringClass() == methods.get(j).getDeclaringClass()) { j++; } if (j - i > 1) { Collections.shuffle(methods.subList(i, j), rnd); } } // Reverse processing order to super...clazz for befores if (ann == Before.class || ann == BeforeClass.class) { Collections.reverse(methods); } methods = Collections.unmodifiableList(methods); shuffledMethodsCache.put(ann, methods); return methods; } /** * Collect all test candidates, regardless if they will be executed or not. At this point * individual test methods are also expanded into multiple executions corresponding * to the number of iterations ({@link #SYSPROP_ITERATIONS}) and the initial method seed * is preassigned. * *

The order of test candidates is shuffled based on the runner's random.

* * @see Rants#RANT_1 */ private List collectTestCandidates(Description classDescription) { // Get the test instance provider if explicitly stated. TestMethodProviders providersAnnotation = suiteClass.getAnnotation(TestMethodProviders.class); // If nothing, fallback to the default. final TestMethodProvider [] providers; if (providersAnnotation != null) { providers = new TestMethodProvider [providersAnnotation.value().length]; int i = 0; for (Class clazz : providersAnnotation.value()) { try { providers[i++] = clazz.newInstance(); } catch (Exception e) { throw new RuntimeException(TestMethodProviders.class.getSimpleName() + " classes could not be instantiated.", e); } } } else { providers = new TestMethodProvider [] { new JUnit4MethodProvider(), // new JUnit3MethodProvider(), }; } // Get test methods from providers. final Set allTestMethods = new HashSet(); for (TestMethodProvider provider : providers) { Collection testMethods = provider.getTestMethods(suiteClass, classModel); allTestMethods.addAll(testMethods); } List testMethods = new ArrayList(allTestMethods); Collections.sort(testMethods, new Comparator() { @Override public int compare(Method m1, Method m2) { return m1.toGenericString().compareTo(m2.toGenericString()); } }); // Perform candidate method validation. validateTestMethods(testMethods); // Shuffle at real test-case level, don't shuffle iterations or explicit @Seeds order. Collections.shuffle(testMethods, new Random(runnerRandomness.getSeed())); final Constructor constructor = suiteClass.getConstructors()[0]; // Collect parameters. ArrayList parameters = new ArrayList(); if (constructor.getParameterTypes().length == 0) { parameters.add(new Object[] {}); } else { try { parameters = collectFactoryParameters(); } catch (AssumptionViolatedException e) { return Collections.emptyList(); } } // TODO: The loops and conditions below are truly horrible... List allTests = new ArrayList(); Map subNodes = new HashMap(); if (parameters.size() > 1) { for (Method method : testMethods) { Description tmp = Description.createSuiteDescription(method.getName()); subNodes.put(method, tmp); suiteDescription.addChild(tmp); } } // Collect annotated parameter names. We could use .class file parsing to get at // the local variables table, but this seems like an overkill. String [] parameterNames = new String [constructor.getParameterTypes().length]; Annotation [][] anns = constructor.getParameterAnnotations(); for (int i = 0; i < parameterNames.length; i++) { for (Annotation ann : anns[i]) { if (ann != null && ann.annotationType().equals(Name.class)) { parameterNames[i] = ((Name) ann).value() + "="; break; } } if (parameterNames[i] == null) { parameterNames[i] = "p" + i + "="; } } for (Object [] params : parameters) { final LinkedHashMap parameterizedArgs = new LinkedHashMap(); for (int i = 0; i < params.length; i++) { parameterizedArgs.put( i < parameterNames.length ? parameterNames[i] : "p" + i + "=", params[i]); } for (Method method : testMethods) { final List methodTests = collectCandidatesForMethod(constructor, params, method, parameterizedArgs); final Description parent; Description tmp = subNodes.get(method); if (tmp == null && methodTests.size() > 1) { tmp = Description.createSuiteDescription(method.getName()); subNodes.put(method, tmp); suiteDescription.addChild(tmp); } else { if (tmp == null) tmp = suiteDescription; } parent = tmp; for (TestCandidate c : methodTests) { parent.addChild(c.description); allTests.add(c); } } } return allTests; } /** * Collect test candidates for a single method and the given seed. */ private List collectCandidatesForMethod( final Constructor constructor, final Object[] params, Method method, LinkedHashMap parameterizedArgs) { final List candidates = new ArrayList(); final boolean fixedSeed = isConstantSeedForAllIterations(method); final int methodIterations = determineMethodIterationCount(method); final long[] seeds = determineMethodSeeds(method); final boolean hasRepetitions = (methodIterations > 1 || seeds.length > 1); int repetition = 0; for (final long testSeed : seeds) { for (int i = 0; i < methodIterations; i++, repetition++) { final long thisSeed = (fixedSeed ? testSeed : testSeed ^ MurmurHash3.hash((long) i)); final LinkedHashMap args = new LinkedHashMap(); if (hasRepetitions) { args.put("#", repetition); } args.putAll(parameterizedArgs); if (hasRepetitions || appendSeedParameter) { args.put("seed=", SeedUtils.formatSeedChain(runnerRandomness, new Randomness(thisSeed))); } Description description = Description.createSuiteDescription( String.format("%s%s(%s)", method.getName(), formatMethodArgs(args), suiteClass.getName()), method.getAnnotations()); // Create an instance and delay instantiation exception if not possible. candidates.add(new TestCandidate(method, thisSeed, description, new InstanceProvider() { @Override public Object newInstance() throws Throwable { try { return constructor.newInstance(params); } catch (InvocationTargetException e) { throw ((InvocationTargetException) e).getTargetException(); } catch (IllegalArgumentException e) { throw new IllegalArgumentException( "Constructor arguments do not match provider parameters?", e); } } @Override public Class getTestClass() { return suiteClass; } })); } } return candidates; } private String formatMethodArgs(LinkedHashMap args) { if (args.isEmpty()) return ""; StringBuilder b = new StringBuilder(); b.append(" {"); for (Iterator> i = args.entrySet().iterator(); i.hasNext();) { Map.Entry e = i.next(); b.append(e.getKey()).append(toString(e.getValue())); if (i.hasNext()) b.append(" "); } b.append("}"); return b.toString(); } /** * Convert value to a stringified form for naming parameterized methods. */ private String toString(Object value) { if (value == null) return "null"; // TODO: handle arrays in a nicer way. return value.toString(); } /** * Collect parameters from factory methods. */ @SuppressWarnings("all") public ArrayList collectFactoryParameters() { ArrayList parameters = new ArrayList(); for (Method m : classModel.getAnnotatedLeafMethods(ParametersFactory.class).keySet()) { Validation.checkThat(m) .isStatic() .isPublic(); ParametersFactory pfAnnotation = m.getAnnotation(ParametersFactory.class); assert pfAnnotation != null; if (!Iterable.class.isAssignableFrom(m.getReturnType())) { throw new RuntimeException("@" + ParametersFactory.class.getSimpleName() + " annotated " + "methods must be public, static and returning Iterable:" + m); } List result = new ArrayList(); try { for (Object [] p : (Iterable) m.invoke(null)) { result.add(p); } } catch (InvocationTargetException e) { Rethrow.rethrow(e.getCause()); } catch (Throwable t) { throw new RuntimeException("Error collecting parameters from: " + m, t); } if (result.isEmpty()) { throw new InternalAssumptionViolatedException("Parameters set should not be empty. Ignoring tests."); } if (pfAnnotation.shuffle()) { Collections.shuffle(result, new Random(runnerRandomness.getSeed())); } parameters.addAll(result); } return parameters; } /** * Determine if a given method's iterations should run with a fixed seed or not. */ private boolean isConstantSeedForAllIterations(Method method) { if (testCaseRandomnessOverride != null) return true; Repeat repeat; if ((repeat = method.getAnnotation(Repeat.class)) != null) { return repeat.useConstantSeed(); } if ((repeat = suiteClass.getAnnotation(Repeat.class)) != null) { return repeat.useConstantSeed(); } return false; } /** * Determine method iteration count based on (first declaration order wins): *
    *
  • global property {@link #SYSPROP_ITERATIONS}.
  • *
  • method annotation {@link Repeat}.
  • *
  • class annotation {@link Repeat}.
  • *
  • The default (1).
  • *
      */ private int determineMethodIterationCount(Method method) { // Global override. if (iterationsOverride != null) return iterationsOverride; Repeat repeat; if ((repeat = method.getAnnotation(Repeat.class)) != null) { return repeat.iterations(); } if ((repeat = suiteClass.getAnnotation(Repeat.class)) != null) { return repeat.iterations(); } return DEFAULT_ITERATIONS; } /** * Determine a given method's initial random seed. * * @see Seed * @see Seeds */ private long [] determineMethodSeeds(Method method) { if (testCaseRandomnessOverride != null) { return new long [] { testCaseRandomnessOverride.getSeed() }; } // We assign each method a different starting hash based on the global seed // and a hash of their name (so that the order of methods does not matter, only // their names). Take into account global override and method and class level // {@link Seed} annotations. final long randomSeed = runnerRandomness.getSeed() ^ MurmurHash3.hash((long) method.getName().hashCode()); final HashSet seeds = new HashSet(); // Check method-level @Seed and @Seeds annotation first. // They take precedence over anything else. Seed seed; if ((seed = method.getAnnotation(Seed.class)) != null) { for (long s : seedFromAnnot(method, randomSeed)) { seeds.add(s); } } // Check a number of seeds on a single method. Seeds seedsValue = classModel.getAnnotation(method, Seeds.class, true); if (seedsValue != null) { for (Seed s : seedsValue.value()) { if (s.value().equals("random")) seeds.add(randomSeed); else { for (long s2 : SeedUtils.parseSeedChain(s.value())) { seeds.add(s2); } } } } // Check suite-level override. if (seeds.isEmpty()) { if ((seed = suiteClass.getAnnotation(Seed.class)) != null) { if (!seed.value().equals("random")) { long [] seedChain = SeedUtils.parseSeedChain(suiteClass.getAnnotation(Seed.class).value()); if (seedChain.length > 1) seeds.add(seedChain[1]); } } } // If still empty, add the derived random seed. if (seeds.isEmpty()) { seeds.add(randomSeed); } long [] result = new long [seeds.size()]; int i = 0; for (Long s : seeds) { result[i++] = s; } return result; } /** * Invoke a given method on a suiteClass instance (can be null for static methods). */ void invoke(Method m, Object instance, Object... args) throws Throwable { if (!Modifier.isPublic(m.getModifiers())) { try { if (!m.isAccessible()) { m.setAccessible(true); } } catch (SecurityException e) { throw new RuntimeException("There is a non-public method that needs to be called. This requires " + "ReflectPermission('suppressAccessChecks'). Don't run with the security manager or " + " add this permission to the runner. Offending method: " + m.toGenericString()); } } try { m.invoke(instance, args); } catch (InvocationTargetException e) { throw e.getCause(); } } /** * Perform additional checks on methods returned from the providers. */ private void validateTestMethods(List testMethods) { HashSet> parents = new HashSet>(); for (Class c = suiteClass; c != null; c = c.getSuperclass()) { parents.add(c); } for (Method method : testMethods) { if (!parents.contains(method.getDeclaringClass())) { throw new IllegalArgumentException("Test method does not belong to " + "test suite class hierarchy: " + method.getDeclaringClass() + "#" + method.getName()); } // * method() Validation.checkThat(method) .describedAs("Test method " + suiteClass.getName() + "#" + method.getName()) .isPublic() .isNotStatic() .hasArgsCount(0); // No @Test(timeout=...) and @Timeout at the same time. Test testAnn = classModel.getAnnotation(method, Test.class, true); if (testAnn != null && testAnn.timeout() > 0 && classModel.isAnnotationPresent(method, Timeout.class, true)) { throw new IllegalArgumentException("Conflicting @Test(timeout=...) and @Timeout " + "annotations in: " + suiteClass.getName() + "#" + method.getName()); } // @Seed annotation on test methods must have at most 1 seed value. Seed seed = classModel.getAnnotation(method, Seed.class, true); if (seed != null) { try { String seedChain = seed.value(); if (!seedChain.equals("random")) { long[] chain = SeedUtils.parseSeedChain(seedChain); if (chain.length > 1) { throw new IllegalArgumentException("@Seed on methods must contain one seed only (no runner seed)."); } } } catch (IllegalArgumentException e) { throw new RuntimeException("@Seed annotation invalid on method " + method.getName() + ", in class " + suiteClass.getName() + ": " + e.getMessage()); } } } } /** * Validate methods and hooks in the suiteClass. Follows "standard" JUnit rules, * with some exceptions on return values and more rigorous checking of shadowed * methods and fields. */ private void validateTarget() { // Target is accessible (public, concrete, has a parameterless constructor etc). Validation.checkThat(suiteClass) .describedAs("Suite class " + suiteClass.getName()) .isPublic() .isConcreteClass(); // Check constructors. Constructor [] constructors = suiteClass.getConstructors(); if (constructors.length != 1 || !Modifier.isPublic(constructors[0].getModifiers())) { throw new RuntimeException("A test class is expected to have one public constructor " + " (parameterless or with types matching static @" + ParametersFactory.class + "-annotated method's output): " + suiteClass.getName()); } // If there is a parameterized constructor, look for a static method that privides parameters. if (constructors[0].getParameterTypes().length > 0) { Collection factories = classModel.getAnnotatedLeafMethods(ParametersFactory.class).keySet(); if (factories.isEmpty()) { throw new RuntimeException("A test class with a parameterized constructor is expected " + " to have a static @" + ParametersFactory.class + "-annotated method: " + suiteClass.getName()); } for (Method m : factories) { Validation.checkThat(m) .describedAs("@ParametersFactory method " + suiteClass.getName() + "#" + m.getName()) .isStatic() .isPublic() .hasArgsCount(0) .hasReturnType(Iterable.class); } } // @BeforeClass for (Method method : classModel.getAnnotatedLeafMethods(BeforeClass.class).keySet()) { Validation.checkThat(method) .describedAs("@BeforeClass method " + suiteClass.getName() + "#" + method.getName()) .isStatic() .hasArgsCount(0); } // @AfterClass for (Method method : classModel.getAnnotatedLeafMethods(AfterClass.class).keySet()) { Validation.checkThat(method) .describedAs("@AfterClass method " + suiteClass.getName() + "#" + method.getName()) .isStatic() .hasArgsCount(0); } // @Before for (Method method : classModel.getAnnotatedLeafMethods(Before.class).keySet()) { Validation.checkThat(method) .describedAs("@Before method " + suiteClass.getName() + "#" + method.getName()) .isNotStatic() .hasArgsCount(0); } // @After for (Method method : classModel.getAnnotatedLeafMethods(After.class).keySet()) { Validation.checkThat(method) .describedAs("@After method " + suiteClass.getName() + "#" + method.getName()) .isNotStatic() .hasArgsCount(0); } // TODO: Validate @Rule fields (what are the "rules" for these anyway?) } /** * Augment stack trace of the given exception with seed infos. */ static T augmentStackTrace(T e, Randomness... seeds) { if (seeds.length == 0) { seeds = RandomizedContext.current().getRandomnesses(); } final String seedChain = SeedUtils.formatSeedChain(seeds); final String existingSeed = seedFromThrowable(e); if (existingSeed != null && existingSeed.equals(seedChain)) { return e; } List stack = new ArrayList( Arrays.asList(e.getStackTrace())); stack.add(0, new StackTraceElement(AUGMENTED_SEED_PACKAGE + ".SeedInfo", "seed", seedChain, 0)); e.setStackTrace(stack.toArray(new StackTraceElement [stack.size()])); return e; } /** * Collect all annotations from a clazz hierarchy. Superclass's annotations come first. * {@link Inherited} annotations are removed (hopefully, the spec. isn't clear on this whether * the same object is returned or not for inherited annotations). */ private static List getAnnotationsFromClassHierarchy(Class clazz, Class annotation) { List anns = new ArrayList(); IdentityHashMap inherited = new IdentityHashMap(); for (Class c = clazz; c != Object.class; c = c.getSuperclass()) { if (c.isAnnotationPresent(annotation)) { T ann = c.getAnnotation(annotation); if (ann.annotationType().isAnnotationPresent(Inherited.class) && inherited.containsKey(ann)) { continue; } anns.add(ann); inherited.put(ann, ann); } } Collections.reverse(anns); return anns; } /** * Get an annotated element's {@link Seed} annotation and determine if it's fixed * or not. If it is fixed, return the seeds. Otherwise return randomSeed. */ private long [] seedFromAnnot(AnnotatedElement element, long randomSeed) { Seed seed = element.getAnnotation(Seed.class); String seedChain = seed.value(); if (seedChain.equals("random")) { return new long [] { randomSeed }; } return SeedUtils.parseSeedChain(seedChain); } /** * Stack trace formatting utilities. These may be initialized to filter out certain packages. */ public TraceFormatting getTraceFormatting() { return traces; } /** * {@link RandomizedRunner} augments stack traces of test methods that ended in an exception * and inserts a fake entry starting with {@link #AUGMENTED_SEED_PACKAGE}. * * @return A string is returned with seeds combined, if any. Null is returned if no augmentation * can be found. */ public static String seedFromThrowable(Throwable t) { StringBuilder b = new StringBuilder(); while (t != null) { for (StackTraceElement s : t.getStackTrace()) { if (s.getClassName().startsWith(AUGMENTED_SEED_PACKAGE)) { if (b.length() > 0) b.append(", "); b.append(s.getFileName()); } } t = t.getCause(); } if (b.length() == 0) return null; else return b.toString(); } /** * Attempts to extract just the method name from parameterized notation. */ public static String methodName(Description description) { return description.getMethodName().replaceAll("\\s?\\{.+\\}", ""); } /** * Returns true if any previous (or current) suite marked with * {@link ThreadLeakZombies.Consequence#IGNORE_REMAINING_TESTS} has * left zombie threads. */ public static boolean hasZombieThreads() { return zombieMarker.get(); } } RandomizedTest.java000066400000000000000000000576541235451432000375170ustar00rootroot00000000000000randomizedtesting-release-2.1.6/randomized-runner/src/main/java/com/carrotsearch/randomizedtestingpackage com.carrotsearch.randomizedtesting; import java.io.Closeable; import java.io.File; import java.io.IOException; import java.net.ServerSocket; import java.nio.charset.Charset; import java.text.SimpleDateFormat; import java.util.Arrays; import java.util.Comparator; import java.util.Date; import java.util.HashMap; import java.util.List; import java.util.Locale; import java.util.Random; import java.util.TimeZone; import org.junit.Assert; import org.junit.Assume; import org.junit.runner.RunWith; import com.carrotsearch.randomizedtesting.annotations.Listeners; import com.carrotsearch.randomizedtesting.annotations.Nightly; import com.carrotsearch.randomizedtesting.generators.*; /** * Common scaffolding for subclassing randomized tests. * * @see Listeners * @see RandomizedContext */ @RunWith(RandomizedRunner.class) public class RandomizedTest extends Assert { /** * The global multiplier property (Double). * * @see #multiplier() */ public static final String SYSPROP_MULTIPLIER = "randomized.multiplier"; /* Commonly used charsets (these must be supported by every JVM). */ protected static final Charset UTF8 = Charset.forName("UTF-8"); protected static final Charset UTF16 = Charset.forName("UTF-16"); protected static final Charset ISO8859_1 = Charset.forName("ISO-8859-1"); protected static final Charset US_ASCII = Charset.forName("US-ASCII"); /* This charset does not need to be supported, but I don't know any JVM under which it wouldn't be. */ protected static final Charset UTF32 = Charset.forName("UTF-32"); /** * Default multiplier. * * @see #SYSPROP_MULTIPLIER */ private static final double DEFAULT_MULTIPLIER = 1.0d; /** * Shortcut for {@link RandomizedContext#current()}. */ public static RandomizedContext getContext() { return RandomizedContext.current(); } /** * Returns true if we're running nightly tests. * @see Nightly */ public static boolean isNightly() { return getContext().isNightly(); } /** * Shortcut for {@link RandomizedContext#getRandom()}. Even though this method * is static, it returns per-thread {@link Random} instance, so no race conditions * can occur. * *

      It is recommended that specific methods are used to pick random values. */ public static Random getRandom() { return getContext().getRandom(); } // // Random value pickers. Shortcuts to methods in {@link #getRandom()} mostly. // public static boolean randomBoolean() { return getRandom().nextBoolean(); } public static byte randomByte() { return (byte) getRandom().nextInt(); } public static short randomShort() { return (short) getRandom().nextInt(); } public static int randomInt() { return getRandom().nextInt(); } public static float randomFloat() { return getRandom().nextFloat(); } public static double randomDouble() { return getRandom().nextDouble(); } public static long randomLong() { return getRandom().nextLong(); } /** @see Random#nextGaussian() */ public static double randomGaussian() { return getRandom().nextGaussian(); } // // Delegates to RandomInts. // /** * A random integer from 0..max (inclusive). */ public static int randomInt(int max) { return RandomInts.randomInt(getRandom(), max); } /** * A random integer from min to max (inclusive). * * @see #scaledRandomIntBetween(int, int) */ public static int randomIntBetween(int min, int max) { return RandomInts.randomIntBetween(getRandom(), min, max); } /** * An alias for {@link #randomIntBetween(int, int)}. * * @see #scaledRandomIntBetween(int, int) */ public static int between(int min, int max) { return randomIntBetween(min, max); } /** * Returns a random value greater or equal to min. The value * picked is affected by {@link #isNightly()} and {@link #multiplier()}. * * @see #scaledRandomIntBetween(int, int) */ public static int atLeast(int min) { if (min < 0) throw new IllegalArgumentException("atLeast requires non-negative argument: " + min); return scaledRandomIntBetween(min, Integer.MAX_VALUE); } /** * Returns a non-negative random value smaller or equal max. The value * picked is affected by {@link #isNightly()} and {@link #multiplier()}. * *

      This method is effectively an alias to: *

         * scaledRandomIntBetween(0, max)
         * 
      * * @see #scaledRandomIntBetween(int, int) */ public static int atMost(int max) { if (max < 0) throw new IllegalArgumentException("atMost requires non-negative argument: " + max); return scaledRandomIntBetween(0, max); } /** * Rarely returns true in about 10% of all calls (regardless of the * {@link #isNightly()} mode). */ public static boolean rarely() { return randomInt(100) >= 90; } /** * The exact opposite of {@link #rarely()}. */ public static boolean frequently() { return !rarely(); } // // Delegates to RandomPicks // /** * Pick a random object from the given array. The array must not be empty. */ public static T randomFrom(T [] array) { return RandomPicks.randomFrom(getRandom(), array); } /** * Pick a random object from the given list. */ public static T randomFrom(List list) { return RandomPicks.randomFrom(getRandom(), list); } // // "multiplied" or scaled value pickers. These will be affected by global multiplier. // /** * A multiplier can be used to linearly scale certain values. It can be used to make data * or iterations of certain tests "heavier" for nightly runs, for example. * *

      The default multiplier value is 1.

      * * @see #SYSPROP_MULTIPLIER * @see #DEFAULT_MULTIPLIER */ public static double multiplier() { checkContext(); return systemPropertyAsDouble(SYSPROP_MULTIPLIER, DEFAULT_MULTIPLIER); } /** * Returns a "scaled" number of iterations for loops which can have a variable * iteration count. This method is effectively * an alias to {@link #scaledRandomIntBetween(int, int)}. */ public static int iterations(int min, int max) { return scaledRandomIntBetween(min, max); } /** * Returns a "scaled" random number between min and max (inclusive). The number of * iterations will fall between [min, max], but the selection will also try to * achieve the points below: *
        *
      • the multiplier can be used to move the number of iterations closer to min * (if it is smaller than 1) or closer to max (if it is larger than 1). Setting * the multiplier to 0 will always result in picking min.
      • *
      • on normal runs, the number will be closer to min than to max.
      • *
      • on nightly runs, the number will be closer to max than to min.
      • *
      * * @see #multiplier() * * @param min Minimum (inclusive). * @param max Maximum (inclusive). * @return Returns a random number between min and max. */ public static int scaledRandomIntBetween(int min, int max) { if (min < 0) throw new IllegalArgumentException("min must be >= 0: " + min); if (min > max) throw new IllegalArgumentException("max must be >= min: " + min + ", " + max); double point = Math.min(1, Math.abs(randomGaussian()) * 0.3) * multiplier(); double range = max - min; int scaled = (int) Math.round(Math.min(point * range, range)); if (isNightly()) { return max - scaled; } else { return min + scaled; } } // Methods to help with I/O and environment. /** * @see #globalTempDir() */ private static File globalTempDir; /** * Subfolders under {@link #globalTempDir} are created synchronously, so we don't need * to mangle filenames. */ private static int tempSubFileNameCount; /** * Global temporary directory created for the duration of this class's lifespan. If * multiple class loaders are used, there may be more global temp dirs, but it * shouldn't really be the case in practice. */ public static File globalTempDir() { checkContext(); synchronized (RandomizedTest.class) { if (globalTempDir == null) { String tempDirPath = System.getProperty("java.io.tmpdir"); if (tempDirPath == null) throw new Error("No property java.io.tmpdir?"); File tempDir = new File(tempDirPath); if (!tempDir.isDirectory() || !tempDir.canWrite()) { throw new Error("Temporary folder not accessible: " + tempDir.getAbsolutePath()); } SimpleDateFormat tsFormat = new SimpleDateFormat("'tests-'yyyyMMddHHmmss'-'SSS"); int retries = 10; do { String dirName = tsFormat.format(new Date()); final File tmpFolder = new File(tempDir, dirName); // I assume mkdir is filesystem-atomic and only succeeds if the // directory didn't previously exist? if (tmpFolder.mkdir()) { globalTempDir = tmpFolder; Runtime.getRuntime().addShutdownHook(new Thread() { public void run() { try { forceDeleteRecursively(globalTempDir); } catch (IOException e) { // Not much else to do but to log and quit. System.err.println("Error while deleting temporary folder '" + globalTempDir.getAbsolutePath() + "': " + e.getMessage()); } if (globalTempDir.exists()) { System.err.println("Could not delete temporary folder entirely: " + globalTempDir.getAbsolutePath()); } } }); return globalTempDir; } } while (retries-- > 0); throw new RuntimeException("Could not create temporary space in: " + tempDir); } return globalTempDir; } } /** * Creates a new temporary directory for the {@link LifecycleScope#TEST} duration. * * @see #globalTempDir() */ public File newTempDir() { return newTempDir(LifecycleScope.TEST); } /** * Creates a temporary directory, deleted after the given lifecycle phase. * Temporary directory is created relative to a globally picked temporary directory. */ public static File newTempDir(LifecycleScope scope) { checkContext(); synchronized (RandomizedTest.class) { File tempDir = new File(globalTempDir(), nextTempName()); if (!tempDir.mkdir()) throw new RuntimeException("Could not create temporary folder: " + tempDir.getAbsolutePath()); getContext().closeAtEnd(new TempPathResource(tempDir), scope); return tempDir; } } /** * Registers a {@link Closeable} resource that should be closed after the test * completes. * * @return resource (for call chaining). */ public T closeAfterTest(T resource) { return getContext().closeAtEnd(resource, LifecycleScope.TEST); } /** * Registers a {@link Closeable} resource that should be closed after the suite * completes. * * @return resource (for call chaining). */ public static T closeAfterSuite(T resource) { return getContext().closeAtEnd(resource, LifecycleScope.SUITE); } /** * Creates a new temporary file for the {@link LifecycleScope#TEST} duration. */ public File newTempFile() { return newTempFile(LifecycleScope.TEST); } /** * Creates a new temporary file deleted after the given lifecycle phase completes. * The file is physically created on disk, but is not locked or opened. */ public static File newTempFile(LifecycleScope scope) { checkContext(); synchronized (RandomizedTest.class) { File tempFile = new File(globalTempDir(), nextTempName()); try { if (!tempFile.createNewFile()) throw new RuntimeException("Could not create temporary file: " + tempFile.getAbsolutePath()); } catch (IOException e) { throw new RuntimeException("Could not create temporary file: " + tempFile.getAbsolutePath(), e); } getContext().closeAtEnd(new TempPathResource(tempFile), scope); return tempFile; } } /** Next temporary filename. */ private static String nextTempName() { return String.format("%04d has-space", tempSubFileNameCount++); } /** * Recursively delete a folder (or file). This attempts to delete everything that * can be deleted, but possibly can leave things behind if files are locked for example. */ static void forceDeleteRecursively(File fileOrDir) throws IOException { if (fileOrDir.isDirectory()) { // We are not checking for symlinks here! for (File f : fileOrDir.listFiles()) { forceDeleteRecursively(f); } } if (!fileOrDir.delete()) { RandomizedRunner.logger.warning("Could not delete: " + fileOrDir.getAbsolutePath()); } } /** * Assign a temporary server socket. If you need a temporary port one can * assign a server socket and close it immediately, just to acquire its port * number. * * @param scope * The lifecycle scope to close the socket after. If the socket is * closed earlier, nothing happens (silently dropped). */ public static ServerSocket newServerSocket(LifecycleScope scope) throws IOException { final ServerSocket socket = new ServerSocket(0); getContext().closeAtEnd(new Closeable() { public void close() throws IOException { if (!socket.isClosed()) socket.close(); } }, scope); return socket; } /** * Return a random Locale from the available locales on the system. * *

      Warning: This test assumes the returned array of locales is repeatable from jvm execution * to jvm execution. It _may_ be different from jvm to jvm and as such, it can render * tests execute in a different way.

      */ public static Locale randomLocale() { Locale[] availableLocales = Locale.getAvailableLocales(); Arrays.sort(availableLocales, new Comparator() { public int compare(Locale o1, Locale o2) { return o1.toString().compareTo(o2.toString()); } }); return randomFrom(availableLocales); } /** * Return a random TimeZone from the available timezones on the system. * *

      Warning: This test assumes the returned array of time zones is repeatable from jvm execution * to jvm execution. It _may_ be different from jvm to jvm and as such, it can render * tests execute in a different way.

      */ public static TimeZone randomTimeZone() { final String[] availableIDs = TimeZone.getAvailableIDs(); Arrays.sort(availableIDs); return TimeZone.getTimeZone(randomFrom(availableIDs)); } // // Characters and strings. Delegates to RandomStrings and that in turn to StringGenerators. // /** @see StringGenerator#ofCodeUnitsLength(Random, int, int) */ public static String randomAsciiOfLengthBetween(int minCodeUnits, int maxCodeUnits) { return RandomStrings.randomAsciiOfLengthBetween(getRandom(), minCodeUnits, maxCodeUnits); } /** @see StringGenerator#ofCodeUnitsLength(Random, int, int) */ public static String randomAsciiOfLength(int codeUnits) { return RandomStrings.randomAsciiOfLength(getRandom(), codeUnits); } /** @see StringGenerator#ofCodeUnitsLength(Random, int, int) */ public static String randomUnicodeOfLengthBetween(int minCodeUnits, int maxCodeUnits) { return RandomStrings.randomUnicodeOfLengthBetween(getRandom(), minCodeUnits, maxCodeUnits); } /** @see StringGenerator#ofCodeUnitsLength(Random, int, int) */ public static String randomUnicodeOfLength(int codeUnits) { return RandomStrings.randomUnicodeOfLength(getRandom(), codeUnits); } /** @see StringGenerator#ofCodePointsLength(Random, int, int) */ public static String randomUnicodeOfCodepointLengthBetween(int minCodePoints, int maxCodePoints) { return RandomStrings.randomUnicodeOfCodepointLengthBetween(getRandom(), minCodePoints, maxCodePoints); } /** @see StringGenerator#ofCodePointsLength(Random, int, int) */ public static String randomUnicodeOfCodepointLength(int codePoints) { return RandomStrings .randomUnicodeOfCodepointLength(getRandom(), codePoints); } /** @see StringGenerator#ofCodeUnitsLength(Random, int, int) */ public static String randomRealisticUnicodeOfLengthBetween(int minCodeUnits, int maxCodeUnits) { return RandomStrings.randomRealisticUnicodeOfLengthBetween(getRandom(), minCodeUnits, maxCodeUnits); } /** @see StringGenerator#ofCodeUnitsLength(Random, int, int) */ public static String randomRealisticUnicodeOfLength(int codeUnits) { return RandomStrings.randomRealisticUnicodeOfLength(getRandom(), codeUnits); } /** @see StringGenerator#ofCodePointsLength(Random, int, int) */ public static String randomRealisticUnicodeOfCodepointLengthBetween( int minCodePoints, int maxCodePoints) { return RandomStrings.randomRealisticUnicodeOfCodepointLengthBetween( getRandom(), minCodePoints, maxCodePoints); } /** @see StringGenerator#ofCodePointsLength(Random, int, int) */ public static String randomRealisticUnicodeOfCodepointLength(int codePoints) { return RandomStrings.randomRealisticUnicodeOfCodepointLength(getRandom(), codePoints); } /** * This is an absolutely hacky utility to take a vararg as input and return the array * of arguments as output. The name is a dollar for brevity, idea borrowed from * http://code.google.com/p/junitparams/. */ public static Object [] $(Object... objects) { return objects; } /** * @see #$ */ public static Object [][] $$(Object[]... objects) { return objects; } // // wrappers for utility methods elsewhere that don't require try..catch blocks // and rethrow the original checked exception if needed. dirty a bit, but saves // keystrokes... // /** * Same as {@link Thread#sleep(long)}. */ public static void sleep(long millis) { try { Thread.sleep(millis); } catch (InterruptedException e) { Rethrow.rethrow(e); } } // // Extensions of Assume (with a message). // /** * Making {@link Assume#assumeTrue(boolean)} directly available. */ public static void assumeTrue(boolean condition) { Assume.assumeTrue(condition); } /** * Reverse of {@link #assumeTrue(boolean)}. */ public static void assumeFalse(boolean condition) { assumeTrue(!condition); } /** * Making {@link Assume#assumeNotNull(Object...)} directly available. */ public static void assumeNotNull(Object... objects) { Assume.assumeNotNull(objects); } /** * @param condition * If false an {@link InternalAssumptionViolatedException} is * thrown by this method and the test case (should be) ignored (or * rather technically, flagged as a failure not passing a certain * assumption). Tests that are assumption-failures do not break * builds (again: typically). * @param message * Message to be included in the exception's string. */ public static void assumeTrue(String message, boolean condition) { if (!condition) { // @see {@link Rants#RANT_2}. throw new InternalAssumptionViolatedException(message); } } /** * Reverse of {@link #assumeTrue(String, boolean)}. */ public static void assumeFalse(String message, boolean condition) { assumeTrue(message, !condition); } /** * Assume t is null. */ public static void assumeNoException(String msg, Throwable t) { if (t != null) { // This does chain the exception as the cause. throw new InternalAssumptionViolatedException(msg, t); } } /** * Making {@link Assume#assumeNoException(Throwable)} directly available. */ public static void assumeNoException(Throwable t) { Assume.assumeNoException(t); } // // System properties and their conversion to common types, with defaults. // /** * Get a system property and convert it to a double, if defined. Otherwise, return the default value. */ public static double systemPropertyAsDouble(String propertyName, double defaultValue) { String v = System.getProperty(propertyName); if (v != null && !v.trim().isEmpty()) { try { return Double.parseDouble(v.trim()); } catch (NumberFormatException e) { throw new IllegalArgumentException("Double value expected for property " + propertyName + ": " + v, e); } } else { return defaultValue; } } /** * Get a system property and convert it to a float, if defined. Otherwise, return the default value. */ public static float systemPropertyAsFloat(String propertyName, float defaultValue) { String v = System.getProperty(propertyName); if (v != null && !v.trim().isEmpty()) { try { return Float.parseFloat(v.trim()); } catch (NumberFormatException e) { throw new IllegalArgumentException("Float value expected for property " + propertyName + ": " + v, e); } } else { return defaultValue; } } /** * Get a system property and convert it to an int, if defined. Otherwise, return the default value. */ public static int systemPropertyAsInt(String propertyName, int defaultValue) { String v = System.getProperty(propertyName); if (v != null && !v.trim().isEmpty()) { try { return Integer.parseInt(v.trim()); } catch (NumberFormatException e) { throw new IllegalArgumentException("Integer value expected for property " + propertyName + ": " + v, e); } } else { return defaultValue; } } /** * Get a system property and convert it to a long, if defined. Otherwise, return the default value. */ public static float systemPropertyAsLong(String propertyName, int defaultValue) { String v = System.getProperty(propertyName); if (v != null && !v.trim().isEmpty()) { try { return Long.parseLong(v.trim()); } catch (NumberFormatException e) { throw new IllegalArgumentException("Long value expected for property " + propertyName + ": " + v, e); } } else { return defaultValue; } } /** Boolean constants mapping. */ @SuppressWarnings("serial") private final static HashMap BOOLEANS = new HashMap() {{ put( "true", true); put( "false", false); put( "on", true); put( "off", false); put( "yes", true); put( "no", false); put("enabled", true); put("disabled", false); }}; /** * Get a system property and convert it to a boolean, if defined. This method returns * true if the property exists an is set to any of the following strings * (case-insensitive): true, on, yes, enabled. * *

      false is returned if the property exists and is set to any of the * following strings (case-insensitive): * false, off, no, disabled. */ public static boolean systemPropertyAsBoolean(String propertyName, boolean defaultValue) { String v = System.getProperty(propertyName); if (v != null && !v.trim().isEmpty()) { v = v.trim(); Boolean result = BOOLEANS.get(v); if (result != null) return result.booleanValue(); else throw new IllegalArgumentException("Boolean value expected for property " + propertyName + " " + "(true/false, on/off, enabled/disabled, yes/no): " + v); } else { return defaultValue; } } // // Miscellaneous infrastructure. // /** * Ensures we're running with an initialized {@link RandomizedContext}. */ private static void checkContext() { // Will throw an exception if not available. RandomizedContext.current(); } } Randomness.java000066400000000000000000000031151235451432000366530ustar00rootroot00000000000000randomizedtesting-release-2.1.6/randomized-runner/src/main/java/com/carrotsearch/randomizedtestingpackage com.carrotsearch.randomizedtesting; import java.util.Random; /** * Per-thread, per-lifecycle state randomness defined as an initial seed and * the current Random instance. * *

      An instance of this class will be typically available from {@link RandomizedContext}. * No need to instantiate manually. * * @see RandomizedContext */ public final class Randomness { private final long seed; private final AssertingRandom random; private SeedDecorator[] decorators; public Randomness(Thread owner, long seed, SeedDecorator... decorators) { this.seed = seed; this.decorators = decorators; this.random = new AssertingRandom(owner, new Random(decorate(seed, decorators))); } public Randomness(long seed, SeedDecorator...decorators) { this(Thread.currentThread(), seed, decorators); } /** Random instance for this randomness. */ public Random getRandom() { return random; } Randomness clone(Thread newOwner) { return new Randomness(newOwner, seed, decorators); } @Override public String toString() { return "[Randomness, seed=" + SeedUtils.formatSeedChain(this) + "]"; } /** * Invalidate the underling {@link #random}. * * @see AssertingRandom#valid */ void destroy() { this.random.destroy(); } /** Starting seed, read-only for tests. */ long getSeed() { return seed; } /** * Decorate a given seed. */ private static long decorate(long seed, SeedDecorator[] decorators) { for (SeedDecorator decorator : decorators) { seed = decorator.decorate(seed); } return seed; } }Rants.java000066400000000000000000000044311235451432000356330ustar00rootroot00000000000000randomizedtesting-release-2.1.6/randomized-runner/src/main/java/com/carrotsearch/randomizedtestingpackage com.carrotsearch.randomizedtesting; import java.lang.reflect.Method; import org.junit.BeforeClass; import org.junit.Ignore; import org.junit.Test; /** * Rants about blocker limitations of JUnit... */ final class Rants { enum RantType { // General ANNOYANCE, DAMN_TERRIBLE, WTF, // Personal ISHOULDHAVEBECOMEALAWYER } /** * TODO: this if freaking dumb... there's absolutely no way to carry test class/ test name * separately from the display name, so we can't easily include seed info on the test * case. If we do, Eclipse complains it cannot find the target class/ test name. If we don't, * Eclipse's JUnit runner gets confused and doesn't show test case execution properly. * * We can't even use a proxy or a subclass because Description has a private constructor. Eh. * * Having a Description properly indicate the test case/ class is useful because we could re-run * a concrete repetition of a given test from the UI. Currently this is impossible - we can * re-run the entire iteration sequence only (or fix the seed on the method, but this requires * changes to the code). */ public static RantType RANT_1 = RantType.DAMN_TERRIBLE; /** * TODO: this if weird default assumption methods (and constructors in AssumptionViolatedException) * do not allow specifying a custom message? */ public static RantType RANT_2 = RantType.ANNOYANCE; /** * TODO: Why is failed assumption propagated as a Failure? This is weird an unnatural. */ public static RantType RANT_3 = RantType.DAMN_TERRIBLE; /** * JUnit is inconsistent in how it treats annotations on methods. Some of them are "inherited" and * some require presence on the exact same {@link Method} as the one used for testing. This has awkward * side effects, for example {@link Ignore} and {@link Test} must co-exist on the same method, not * on virtual method hierarchy. You cannot make {@link Test} methods protected and publish them in * subclasses. Shadowing of {@link BeforeClass} methods is inconsistent (non-annotated shadowed method * will not be called, shadowed method annotated with {@link BeforeClass} prevents the shadowed method * from being called), etc. */ public static RantType RANT_4 = RantType.DAMN_TERRIBLE; } ReproduceErrorMessageBuilder.java000066400000000000000000000055201235451432000423220ustar00rootroot00000000000000randomizedtesting-release-2.1.6/randomized-runner/src/main/java/com/carrotsearch/randomizedtestingpackage com.carrotsearch.randomizedtesting; import java.util.Arrays; import org.junit.runner.Description; import static com.carrotsearch.randomizedtesting.SysGlobals.*; import static com.carrotsearch.randomizedtesting.RandomizedRunner.*; /** * A builder for constructing "reproduce with" message. * * @see #appendAllOpts(Description) */ public class ReproduceErrorMessageBuilder { private final StringBuilder b; public ReproduceErrorMessageBuilder() { this(new StringBuilder()); } public ReproduceErrorMessageBuilder(StringBuilder builder) { this.b = builder; } /** * Append all JVM options that may help in reproducing the error. Options are * appended to the provided StringBuilder in the "command-line" syntax of: *

         * -Doption="value"
         * 
      * * @param description Suite or test description. */ public ReproduceErrorMessageBuilder appendAllOpts(Description description) { RandomizedContext ctx = null; try { ctx = RandomizedContext.current(); appendOpt(SYSPROP_RANDOM_SEED(), ctx.getRunnerSeedAsString()); } catch (IllegalStateException e) { logger.warning("No context available when dumping reproduce options?"); } if (description.getClassName() != null) { appendOpt(SYSPROP_TESTCLASS(), description.getClassName()); } if (description.getMethodName() != null) { appendOpt(SYSPROP_TESTMETHOD(), methodName(description)); } appendRunnerProperties(); appendTestGroupOptions(ctx); appendEnvironmentSettings(); return this; } public ReproduceErrorMessageBuilder appendEnvironmentSettings() { for (String sysPropName : Arrays.asList( "file.encoding", "user.timezone")) { if (emptyToNull(System.getProperty(sysPropName)) != null) { appendOpt(sysPropName, System.getProperty(sysPropName)); } } return this; } public ReproduceErrorMessageBuilder appendTestGroupOptions(RandomizedContext ctx) { if (ctx != null) { ctx.getGroupEvaluator().appendGroupFilteringOptions(this); } return this; } public ReproduceErrorMessageBuilder appendRunnerProperties() { appendOpt(SYSPROP_PREFIX(), CURRENT_PREFIX()); for (String sysPropName : Arrays.asList( SYSPROP_STACKFILTERING(), SYSPROP_ITERATIONS(), SYSPROP_KILLATTEMPTS(), SYSPROP_KILLWAIT(), SYSPROP_TIMEOUT())) { if (System.getProperty(sysPropName) != null) { appendOpt(sysPropName, System.getProperty(sysPropName)); } } return this; } /** * Append a single VM option. */ public ReproduceErrorMessageBuilder appendOpt(String sysPropName, String value) { if (b.length() > 0) { b.append(" "); } // TODO: quoting in case of spaces, quotes etc? b.append("-D").append(sysPropName).append("=").append(value); return this; } } ResourceDisposalError.java000066400000000000000000000005251235451432000410440ustar00rootroot00000000000000randomizedtesting-release-2.1.6/randomized-runner/src/main/java/com/carrotsearch/randomizedtestingpackage com.carrotsearch.randomizedtesting; /** * Thrown when a resource could not be released. * * @see RandomizedContext#closeAtEnd(java.io.Closeable, LifecycleScope) */ @SuppressWarnings("serial") class ResourceDisposalError extends Error { public ResourceDisposalError(String msg, Throwable cause) { super(msg, cause); } } Rethrow.java000066400000000000000000000011471235451432000361770ustar00rootroot00000000000000randomizedtesting-release-2.1.6/randomized-runner/src/main/java/com/carrotsearch/randomizedtestingpackage com.carrotsearch.randomizedtesting; /** * Rethrowing checked exceptions as unchecked ones. Eh, it is sometimes useful... */ public final class Rethrow { /** * Classy puzzler to rethrow any checked exception as an unchecked one. */ @SuppressWarnings("all") private static class Rethrower { private void rethrow(Throwable t) throws T { throw (T) t; } } /** * Rethrows t (identical object). */ public static RuntimeException rethrow(Throwable t) { new Rethrower().rethrow(t); // Inaccessible. return null; } } RunnerThreadGroup.java000066400000000000000000000020701235451432000401570ustar00rootroot00000000000000randomizedtesting-release-2.1.6/randomized-runner/src/main/java/com/carrotsearch/randomizedtestingpackage com.carrotsearch.randomizedtesting; import java.util.logging.Level; import java.util.logging.Logger; /** * A {@link ThreadGroup} under which all tests (and hooks) are executed. Theoretically, there * should be no thread outside of this group's control. */ final class RunnerThreadGroup extends ThreadGroup { /* */ RunnerThreadGroup(String name) { super(name); } /** * Capture all uncaught exceptions from this group's threads. */ @Override public void uncaughtException(Thread t, Throwable e) { // Try to get the context for this thread and augment the exception with the seed. try { e = RandomizedRunner.augmentStackTrace(e); } catch (Throwable ignore) { // if there's none, don't panic, but this is weird and should not happen. Logger.getLogger(RunnerThreadGroup.class.getSimpleName()) .log(Level.SEVERE, RunnerThreadGroup.class.getSimpleName() + "'s sub thread should " + "always have a context and it didn't have any?", ignore); } super.uncaughtException(t, e); } } SeedDecorator.java000066400000000000000000000007051235451432000372670ustar00rootroot00000000000000randomizedtesting-release-2.1.6/randomized-runner/src/main/java/com/carrotsearch/randomizedtestingpackage com.carrotsearch.randomizedtesting; import com.carrotsearch.randomizedtesting.annotations.SeedDecorators; /** * This is an advanced feature. See {@link SeedDecorators} annotation. */ public interface SeedDecorator { /** * Called once after instantiation to set up the decorator. */ void initialize(Class suiteClass); /** * Called to decorate the initial seed for a {@link Randomness}. */ long decorate(long seed); } SeedUtils.java000066400000000000000000000037541235451432000364540ustar00rootroot00000000000000randomizedtesting-release-2.1.6/randomized-runner/src/main/java/com/carrotsearch/randomizedtestingpackage com.carrotsearch.randomizedtesting; /** * Utilities for parsing random seeds. */ public final class SeedUtils { private final static char [] HEX = "0123456789ABCDEF".toCharArray(); private SeedUtils() {} /** * Parse a single seed. The seed needs to be cleaned up from any surrounding characters. */ public static long parseSeed(String seed) { long result = 0; for (char chr : seed.toCharArray()) { chr = Character.toLowerCase(chr); result = result << 4; if (chr >= '0' && chr <= '9') result |= (chr - '0'); else if (chr >= 'a' && chr <= 'f') result |= (chr - 'a' + 10); else throw new IllegalArgumentException("Expected hexadecimal seed: " + seed); } return result; } /** * Format a single seed. */ public static String formatSeed(long seed) { StringBuilder b = new StringBuilder(); do { b.append(HEX[(int) (seed & 0xF)]); seed = seed >>> 4; } while (seed != 0); return b.reverse().toString(); } /** * Parse a seed chain formatted with {@link SeedUtils#formatSeedChain(Randomness...)}. */ public static long [] parseSeedChain(String chain) { chain = chain.replaceAll("[\\[\\]]", ""); if (!chain.matches("[0-9A-Fa-f\\:]+")) { throw new IllegalArgumentException("Not a valid seed chain: " + chain); } String [] splits = chain.split("[\\:]"); long [] longs = new long [splits.length]; for (int i = 0; i < splits.length; i++) longs[i] = parseSeed(splits[i]); return longs; } /** * Formats randomness seed or seeds into something the user can type in to get predictably repeatable * execution. */ public static String formatSeedChain(Randomness... randomnesses) { StringBuilder b = new StringBuilder(); b.append("["); for (int i = 0; i < randomnesses.length; i++) { if (i > 0) b.append(":"); b.append(formatSeed(randomnesses[i].getSeed())); } b.append("]"); return b.toString(); } } StackTraceHolder.java000066400000000000000000000004741235451432000377310ustar00rootroot00000000000000randomizedtesting-release-2.1.6/randomized-runner/src/main/java/com/carrotsearch/randomizedtestingpackage com.carrotsearch.randomizedtesting; /** * This is never thrown. The only purpose it serves it to carry chained stack traces * for informational purposes. */ @SuppressWarnings("serial") final class StackTraceHolder extends Throwable { public StackTraceHolder(String message) { super(message); } } SysGlobals.java000066400000000000000000000205361235451432000366320ustar00rootroot00000000000000randomizedtesting-release-2.1.6/randomized-runner/src/main/java/com/carrotsearch/randomizedtestingpackage com.carrotsearch.randomizedtesting; import org.junit.runners.JUnit4; import com.carrotsearch.randomizedtesting.annotations.Repeat; import com.carrotsearch.randomizedtesting.annotations.Seeds; /** * Global names for system properties controlling the behavior of {@link JUnit4} ANT task * and {@link RandomizedRunner}. */ public final class SysGlobals { /** System property passed to forked VMs: VM ID (sequential integer between 0 and the (number of concurrent jvms - 1)). */ public static final String CHILDVM_SYSPROP_JVM_ID = "junit4.childvm.id"; /** System property passed to forked VMs: the number of concurrent JVMs. */ public static final String CHILDVM_SYSPROP_JVM_COUNT = "junit4.childvm.count"; private final static Object lock = new Object(); /** * Default prefix for all properties. */ private static final String DEFAULT_PREFIX = "tests"; /** * A common prefix for all system properties used by randomizedtesting * packages. It is discouraged to change this property but it may be used to resolve * conflicts with packages that have overlapping property names. */ private static final String SYSPROP_PREFIX = DEFAULT_PREFIX + ".prefix"; /** * Global singleton. Initialized once. */ private static SysGlobals singleton; /** * Singleton initialization stack for easier debugging. */ private static StackTraceElement[] singletonInitStack; /** Initialized singleton's prefix. */ private final String prefix; /* Property names, rendered. */ private final String SYSPROP_STACKFILTERING; private final String SYSPROP_RANDOM_SEED; private final String SYSPROP_ITERATIONS; private final String SYSPROP_TESTCLASS; private final String SYSPROP_TESTMETHOD; private final String SYSPROP_TESTFILTER; private final String SYSPROP_KILLATTEMPTS; private final String SYSPROP_KILLWAIT; private final String SYSPROP_TIMEOUT; private final String SYSPROP_TIMEOUT_SUITE; private final String SYSPROP_APPEND_SEED; // Singleton constructor. private SysGlobals(String prefix) { this.prefix = prefix; this.SYSPROP_STACKFILTERING = prefixWith(prefix, "stackfiltering"); this.SYSPROP_RANDOM_SEED = prefixWith(prefix, "seed"); this.SYSPROP_ITERATIONS = prefixWith(prefix, "iters"); this.SYSPROP_TESTCLASS = prefixWith(prefix, "class"); this.SYSPROP_TESTMETHOD = prefixWith(prefix, "method"); this.SYSPROP_TESTFILTER = prefixWith(prefix, "filter"); this.SYSPROP_KILLATTEMPTS = prefixWith(prefix, "killattempts"); this.SYSPROP_KILLWAIT = prefixWith(prefix, "killwait"); this.SYSPROP_TIMEOUT = prefixWith(prefix, "timeout"); this.SYSPROP_TIMEOUT_SUITE = prefixWith(prefix, "timeoutSuite"); this.SYSPROP_APPEND_SEED = prefixWith(prefix, "appendseed"); } /** */ private String prefixWith(String prefix, String propertyName) { if (prefix.isEmpty()) { return propertyName; } else { return prefix + (prefix.endsWith(".") ? "" : ".") + propertyName; } } /** */ private static SysGlobals singleton() { synchronized (lock) { if (singleton == null) { String prefix = System.getProperty(SYSPROP_PREFIX); if (prefix == null) { prefix = DEFAULT_PREFIX; } initializeWith(prefix); } return singleton; } } /** */ public static SysGlobals initializeWith(String prefix) { if (prefix == null) { throw new IllegalArgumentException("Prefix must not be null."); } synchronized (lock) { if (singleton == null) { singleton = new SysGlobals(prefix); singletonInitStack = Thread.currentThread().getStackTrace(); } if (!singleton.prefix.equals(prefix)) { Exception e = new Exception("Original singleton initialization stack."); e.setStackTrace(singletonInitStack); throw new RuntimeException("A singleton has been initialized already with a " + "different prefix: existing=" + singleton.prefix + ", attempted=" + prefix, e); } return singleton; } } /** * Global system property that holds the prefix used by other properties. */ public static String SYSPROP_PREFIX() { return SYSPROP_PREFIX; } /** * Static singleton's property prefix. Initializes it if not already initialized. */ public static String CURRENT_PREFIX() { return singleton().prefix; } /** * Enable or disable stack filtering. */ public static String SYSPROP_STACKFILTERING() { return singleton().SYSPROP_STACKFILTERING; } /** * System property with an integer defining global initialization seeds for all * random generators. Should guarantee test reproducibility. */ public static String SYSPROP_RANDOM_SEED() { return singleton().SYSPROP_RANDOM_SEED; } /** * The global override for the number of each test's repetitions. */ public static String SYSPROP_ITERATIONS() { return singleton().SYSPROP_ITERATIONS; } /** * Global override for picking out a single test class to execute. All other * classes are ignored. The property can contain "globbing patterns" similar * to shell expansion patterns. For example: *
         * *MyTest
         * 
      * will pick all classes ending in MyTest (in any package, including nested static * classes if they appear on input). */ public static String SYSPROP_TESTCLASS() { return singleton().SYSPROP_TESTCLASS; } /** * Global override for picking out a single test method to execute. If a * matching method exists in more than one class, it will be executed. */ public static String SYSPROP_TESTMETHOD() { return singleton().SYSPROP_TESTMETHOD; } /** * Global test filter. */ public static String SYSPROP_TESTFILTER() { return singleton().SYSPROP_TESTFILTER; } /** * If there's a runaway thread, how many times do we try to interrupt and * then kill it before we give up? Runaway threads may affect other tests (bad idea). * * @see #SYSPROP_KILLWAIT */ public static String SYSPROP_KILLATTEMPTS() { return singleton().SYSPROP_KILLATTEMPTS; } /** * If there's a runaway thread, how long should we wait between iterations of * putting a silver bullet through its heart? * * @see #SYSPROP_KILLATTEMPTS */ public static String SYSPROP_KILLWAIT() { return singleton().SYSPROP_KILLWAIT; } /** * Global override for a single test case's maximum execution time after which * it is considered out of control and an attempt to interrupt it is executed. * *

      The timeout value should be in milliseconds. If the value is trailed by a * "!" then the timeout value takes precedence over annotations, otherwise annotations * take precedence over the default timeout. This is useful for running debugging * sessions, for example, when default timeouts may be too short. * * @see RandomizedRunner#DEFAULT_TIMEOUT */ public static String SYSPROP_TIMEOUT() { return singleton().SYSPROP_TIMEOUT; } /** * Global override for entire suite's maximum execution time after which * it is considered out of control. * *

      The timeout value should be in milliseconds. If the value is trailed by a * "!" then the timeout value takes precedence over annotations, otherwise annotations * take precedence over the default timeout. This is useful for running debugging * sessions, for example, when default timeouts may be too short. * * @see RandomizedRunner#DEFAULT_TIMEOUT_SUITE */ public static String SYSPROP_TIMEOUT_SUITE() { return singleton().SYSPROP_TIMEOUT_SUITE; } /** * If true, append seed parameter to all methods. Methods that are for some * reason repeated (due to {@link Repeat} annotation or multiple {@link Seeds}, for example) * are always postfixed with the seed to discriminate tests from each other. Otherwise many * GUI clients have a problem in telling which test result was which. */ public static String SYSPROP_APPEND_SEED() { return singleton().SYSPROP_APPEND_SEED; } /** * Prefix a given property name with a common prefix. The prefix itself can be overridden * using {@link #SYSPROP_PREFIX}. This method initializes static singleton property * names so it shouldn't be called on class initialization anywhere. */ public static String prefixProperty(String propertyName) { return singleton().prefixWith(singleton.prefix, propertyName); } } TempPathResource.java000066400000000000000000000012071235451432000377740ustar00rootroot00000000000000randomizedtesting-release-2.1.6/randomized-runner/src/main/java/com/carrotsearch/randomizedtestingpackage com.carrotsearch.randomizedtesting; import java.io.*; /** * A temporary path resource will be deleted at the end of a given lifecycle phase. * * @see RandomizedContext#closeAtEnd(Closeable, LifecycleScope) * @see RandomizedTest#newTempDir() */ public class TempPathResource implements Closeable { private final File location; public TempPathResource(File location) { this.location = location; } public void close() throws IOException { RandomizedTest.forceDeleteRecursively(location); if (location.exists()) throw new IOException("Could not remove path: " + location.getAbsolutePath()); } } TestMethodProvider.java000066400000000000000000000017471235451432000403460ustar00rootroot00000000000000randomizedtesting-release-2.1.6/randomized-runner/src/main/java/com/carrotsearch/randomizedtestingpackage com.carrotsearch.randomizedtesting; import java.lang.reflect.Method; import java.util.Collection; /** * Responsible for providing individual test instances and their descriptions. Also * performs class validation to ensure test methods are valid. */ public interface TestMethodProvider { /** * Determine which methods are test methods. The contract is that methods must * be public, instance bound (not static) and parameterless. No other * restrictions apply (as if these weren't enough...). * * @param suiteClass * The suite class. * @param suiteClassModel * A precomputed model of the suite class including method annotations and * class hierarchy walking utilities. This is made available for performance * reasons only. * @return Return a set of methods which should be invoked by the runner as * tests. */ Collection getTestMethods(Class suiteClass, ClassModel suiteClassModel); } ThreadFilter.java000066400000000000000000000005061235451432000371200ustar00rootroot00000000000000randomizedtesting-release-2.1.6/randomized-runner/src/main/java/com/carrotsearch/randomizedtestingpackage com.carrotsearch.randomizedtesting; import com.carrotsearch.randomizedtesting.annotations.ThreadLeakFilters; /** * @see ThreadLeakFilters */ public interface ThreadFilter { /** * @return Return true if thread t should be * filtered out. */ public boolean reject(Thread t); }ThreadLeakControl.java000066400000000000000000000670551235451432000401240ustar00rootroot00000000000000randomizedtesting-release-2.1.6/randomized-runner/src/main/java/com/carrotsearch/randomizedtestingpackage com.carrotsearch.randomizedtesting; import static com.carrotsearch.randomizedtesting.RandomizedRunner.DEFAULT_KILLATTEMPTS; import static com.carrotsearch.randomizedtesting.RandomizedRunner.DEFAULT_KILLWAIT; import static com.carrotsearch.randomizedtesting.RandomizedRunner.DEFAULT_TIMEOUT; import static com.carrotsearch.randomizedtesting.RandomizedRunner.DEFAULT_TIMEOUT_SUITE; import static com.carrotsearch.randomizedtesting.RandomizedTest.systemPropertyAsInt; import static com.carrotsearch.randomizedtesting.SysGlobals.SYSPROP_KILLATTEMPTS; import static com.carrotsearch.randomizedtesting.SysGlobals.SYSPROP_KILLWAIT; import static com.carrotsearch.randomizedtesting.SysGlobals.SYSPROP_TIMEOUT; import static com.carrotsearch.randomizedtesting.SysGlobals.SYSPROP_TIMEOUT_SUITE; import java.lang.annotation.Annotation; import java.lang.management.ManagementFactory; import java.lang.management.ThreadInfo; import java.lang.reflect.AnnotatedElement; import java.util.ArrayList; import java.util.Arrays; import java.util.Collection; import java.util.Collections; import java.util.EnumSet; import java.util.Formatter; import java.util.HashMap; import java.util.HashSet; import java.util.Iterator; import java.util.List; import java.util.Locale; import java.util.Map; import java.util.Set; import java.util.concurrent.atomic.AtomicBoolean; import java.util.logging.Logger; import org.junit.Test; import org.junit.internal.AssumptionViolatedException; import org.junit.runner.Description; import org.junit.runner.Result; import org.junit.runner.notification.Failure; import org.junit.runner.notification.RunListener; import org.junit.runner.notification.RunNotifier; import org.junit.runner.notification.StoppedByUserException; import org.junit.runners.model.MultipleFailureException; import org.junit.runners.model.Statement; import com.carrotsearch.randomizedtesting.RandomizedRunner.TestCandidate; import com.carrotsearch.randomizedtesting.RandomizedRunner.UncaughtException; import com.carrotsearch.randomizedtesting.annotations.ThreadLeakAction; import com.carrotsearch.randomizedtesting.annotations.ThreadLeakAction.Action; import com.carrotsearch.randomizedtesting.annotations.ThreadLeakFilters; import com.carrotsearch.randomizedtesting.annotations.ThreadLeakGroup; import com.carrotsearch.randomizedtesting.annotations.ThreadLeakLingering; import com.carrotsearch.randomizedtesting.annotations.ThreadLeakScope; import com.carrotsearch.randomizedtesting.annotations.ThreadLeakScope.Scope; import com.carrotsearch.randomizedtesting.annotations.ThreadLeakZombies; import com.carrotsearch.randomizedtesting.annotations.Timeout; import com.carrotsearch.randomizedtesting.annotations.TimeoutSuite; /** * Everything corresponding to thread leak control. This is very, very fragile to changes * because of how threads interact and where they can be spun off. */ @SuppressWarnings("resource") class ThreadLeakControl { /** A dummy class serving as the source of defaults for annotations. */ @ThreadLeakScope @ThreadLeakAction @ThreadLeakLingering @ThreadLeakZombies @ThreadLeakFilters @ThreadLeakGroup private static class DefaultAnnotationValues {} /** * Shared logger. */ private final static Logger logger = RandomizedRunner.logger; /** * How many attempts to interrupt and then kill a runaway thread before giving up? */ private final int killAttempts; /** * How long to wait between attempts to kill a runaway thread (millis). */ private final int killWait; /** * Target notifier. */ private final RunNotifier targetNotifier; /** * This is the assumed set of threads without leaks. */ private final Set expectedSuiteState; /** * Atomic section for passing notifier events. */ private final Object notifierLock = new Object(); /** * @see SubNotifier */ private final SubNotifier subNotifier; /** * Test timeout. */ private TimeoutValue testTimeout; /** * Suite timeout. */ private TimeoutValue suiteTimeout; /** * Built-in filters. */ private final List builtinFilters; /** * User filter (compound). */ private ThreadFilter suiteFilters; /** * The governing runner. */ private final RandomizedRunner runner; /** * Suite timeout. */ private AtomicBoolean suiteTimedOut = new AtomicBoolean(); /** * Thread leak detection group. */ ThreadLeakGroup threadLeakGroup; /** * Sub-notifier that controls passing events back in case of timeouts. */ private class SubNotifier extends RunNotifier { private boolean stopRequested = false; Description testInProgress; @Override public void addListener(RunListener listener) { throw new UnsupportedOperationException(); } @Override public void addFirstListener(RunListener listener) { throw new UnsupportedOperationException(); } @Override public void removeListener(RunListener listener) { throw new UnsupportedOperationException(); } @Override public void fireTestRunFinished(Result result) { throw new UnsupportedOperationException(); } @Override public void fireTestRunStarted(Description description) { throw new UnsupportedOperationException(); } @Override public void fireTestStarted(Description description) throws StoppedByUserException { synchronized (notifierLock) { if (stopRequested) return; targetNotifier.fireTestStarted(description); testInProgress = description; } } @Override public void fireTestAssumptionFailed(Failure failure) { synchronized (notifierLock) { if (stopRequested) return; targetNotifier.fireTestAssumptionFailed(failure); } } @Override public void fireTestFailure(Failure failure) { synchronized (notifierLock) { if (stopRequested) return; targetNotifier.fireTestFailure(failure); } } @Override public void fireTestIgnored(Description description) { synchronized (notifierLock) { if (stopRequested) return; testInProgress = null; targetNotifier.fireTestIgnored(description); } } @Override public void fireTestFinished(Description description) { synchronized (notifierLock) { if (stopRequested) return; testInProgress = null; targetNotifier.fireTestFinished(description); } } /** * Detach from target notifier. */ @Override public void pleaseStop() { stopRequested = true; } } /** * Timeout parsing code and logic. */ private static class TimeoutValue { private final int timeoutOverride; private final boolean globalTimeoutFirst; TimeoutValue(String sysprop, int defaultValue) { String timeoutValue = System.getProperty(sysprop); boolean globalTimeoutFirst = false; if (timeoutValue == null || timeoutValue.trim().length() == 0) { timeoutValue = null; } if (timeoutValue != null) { // Check for timeout precedence. globalTimeoutFirst = timeoutValue.matches("[0-9]+\\!"); timeoutValue = timeoutValue.replaceAll("\\!", ""); } else { timeoutValue = Integer.toString(defaultValue); } this.timeoutOverride = Integer.parseInt(timeoutValue); this.globalTimeoutFirst = globalTimeoutFirst; } int getTimeout(Integer value) { if (globalTimeoutFirst) { return timeoutOverride; } else { return value != null ? value : timeoutOverride; } } } /** */ private static class ThisThreadFilter implements ThreadFilter { private final Thread t; public ThisThreadFilter(Thread t) { this.t = t; } @Override public boolean reject(Thread t) { return this.t == t; } } private static ThreadFilter or(final ThreadFilter... filters) { return new ThreadFilter() { @Override public boolean reject(Thread t) { boolean reject = false; for (ThreadFilter f : filters) { if (reject |= f.reject(t)) { break; } } return reject; } }; } /** */ private static class KnownSystemThread implements ThreadFilter { @Override public boolean reject(Thread t) { // Explicit check for system group. ThreadGroup tgroup = t.getThreadGroup(); if (tgroup != null && "system".equals(tgroup.getName()) && tgroup.getParent() == null) { return true; } // Explicit check for Serializer shutdown daemon. if (t.getName().equals("JUnit4-serializer-daemon")) { return true; } // Explicit check for java flight recorder (jfr) threads. if (t.getName().equals("JFR request timer")) { return true; } // J9 memory pool thread. if (t.getName().equals("MemoryPoolMXBean notification dispatcher")) { return true; } // Explicit check for MacOSX AWT-AppKit if (t.getName().equals("AWT-AppKit")) { return true; } // Explicit check for TokenPoller (MessageDigest spawns it). if (t.getName().contains("Poller SunPKCS11")) { return true; } // forked process reaper on Unixish systems if (t.getName().equals("process reaper")) { return true; } final List stack = new ArrayList(Arrays.asList(t.getStackTrace())); Collections.reverse(stack); // Explicit check for GC$Daemon if (stack.size() >= 1 && stack.get(0).getClassName().startsWith("sun.misc.GC$Daemon")) { return true; } return false; } } /** */ ThreadLeakControl(RunNotifier notifier, RandomizedRunner runner) { this.targetNotifier = notifier; this.subNotifier = new SubNotifier(); this.runner = runner; this.killAttempts = systemPropertyAsInt(SYSPROP_KILLATTEMPTS(), DEFAULT_KILLATTEMPTS); this.killWait = systemPropertyAsInt(SYSPROP_KILLWAIT(), DEFAULT_KILLWAIT); // Determine default timeouts. testTimeout = new TimeoutValue(SYSPROP_TIMEOUT(), DEFAULT_TIMEOUT); suiteTimeout = new TimeoutValue(SYSPROP_TIMEOUT_SUITE(), DEFAULT_TIMEOUT_SUITE); builtinFilters = Arrays.asList( new ThisThreadFilter(Thread.currentThread()), new KnownSystemThread()); // Determine a set of expected threads up front (unfiltered). expectedSuiteState = Collections.unmodifiableSet(Threads.getAllThreads()); } /** * Runs a {@link Statement} and keeps any exception and * completion flag. */ private static class StatementRunner implements Runnable { private final Statement s; volatile Throwable error; volatile boolean completed; StatementRunner(Statement s) { this.s = s; } public void run() { try { s.evaluate(); } catch (Throwable t) { error = t; } finally { completed = true; } } } /** * Check on zombie threads status. */ private static void checkZombies() throws AssumptionViolatedException { if (RandomizedRunner.hasZombieThreads()) { throw new AssumptionViolatedException("Leaked background threads present (zombies)."); } } /** * A {@link Statement} for wrapping suite-level execution. */ Statement forSuite(final Statement s, final Description suiteDescription) { final Class suiteClass = RandomizedContext.current().getTargetClass(); final int timeout = determineTimeout(suiteClass); return new Statement() { @Override public void evaluate() throws Throwable { checkZombies(); threadLeakGroup = firstAnnotated(ThreadLeakGroup.class, suiteClass, DefaultAnnotationValues.class); final List errors = new ArrayList(); suiteFilters = instantiateFilters(errors, suiteClass); MultipleFailureException.assertEmpty(errors); final StatementRunner sr = new StatementRunner(s); final boolean timedOut = forkTimeoutingTask(sr, timeout, errors); synchronized (notifierLock) { if (timedOut) { // Mark as timed out so that we don't do any checks in any currently running test suiteTimedOut.set(true); // Flush streams so that we don't get warning outputs before sysout buffers. System.out.flush(); System.err.flush(); // Emit a warning. logger.warning("Suite execution timed out: " + suiteDescription + formatThreadStacksFull()); // mark subNotifier as dead (no longer passing events). subNotifier.pleaseStop(); } } if (timedOut) { // complete subNotifier state in case in the middle of a test. if (subNotifier.testInProgress != null) { targetNotifier.fireTestFailure( new Failure(subNotifier.testInProgress, RandomizedRunner.augmentStackTrace( emptyStack(new Exception("Test abandoned because suite timeout was reached."))))); targetNotifier.fireTestFinished(subNotifier.testInProgress); } // throw suite failure (timeout). errors.add(RandomizedRunner.augmentStackTrace( emptyStack(new Exception("Suite timeout exceeded (>= " + timeout + " msec).")))); } final AnnotatedElement [] chain = { suiteClass, DefaultAnnotationValues.class }; List threadLeakErrors = timedOut ? new ArrayList() : errors; checkThreadLeaks( refilter(expectedSuiteState, suiteFilters), threadLeakErrors, LifecycleScope.SUITE, suiteDescription, chain); processUncaught(errors, runner.handler.getUncaughtAndClear()); MultipleFailureException.assertEmpty(errors); } }; } /** * A {@link Statement} for wrapping test-level execution. */ Statement forTest(final Statement s, final TestCandidate c) { final int timeout = determineTimeout(c); return new Statement() { @Override public void evaluate() throws Throwable { checkZombies(); final StatementRunner sr = new StatementRunner(s); final List errors = new ArrayList(); final Set beforeTestState = getThreads(suiteFilters); final boolean timedOut = forkTimeoutingTask(sr, timeout, errors); if (suiteTimedOut.get()) { return; } if (timedOut) { logger.warning("Test execution timed out: " + c.description + formatThreadStacksFull()); } if (timedOut) { errors.add(RandomizedRunner.augmentStackTrace( emptyStack(new Exception("Test timeout exceeded (>= " + timeout + " msec).")))); } final AnnotatedElement [] chain = { c.method, c.instanceProvider.getTestClass(), DefaultAnnotationValues.class }; List threadLeakErrors = timedOut ? new ArrayList() : errors; checkThreadLeaks(beforeTestState, threadLeakErrors, LifecycleScope.TEST, c.description, chain); processUncaught(errors, runner.handler.getUncaughtAndClear()); MultipleFailureException.assertEmpty(errors); } }; } /** * Refilter a set of threads */ protected Set refilter(Set in, ThreadFilter f) { HashSet t = new HashSet(in); for (Iterator i = t.iterator(); i.hasNext();) { if (f.reject(i.next())) { i.remove(); } } return t; } /** * Instantiate a full set of {@link ThreadFilter}s for a suite. */ private ThreadFilter instantiateFilters(List errors, Class suiteClass) { ThreadLeakFilters ann = firstAnnotated(ThreadLeakFilters.class, suiteClass, DefaultAnnotationValues.class); final ArrayList filters = new ArrayList(); for (Class c : ann.filters()) { try { filters.add(c.newInstance()); } catch (Throwable t) { errors.add(t); } } if (ann.defaultFilters()) { filters.addAll(builtinFilters); } return or(filters.toArray(new ThreadFilter[filters.size()])); } /** * Clears a {@link Throwable}'s stack. */ private static T emptyStack(T t) { t.setStackTrace(new StackTraceElement [0]); return t; } /** * Process uncaught exceptions. */ protected void processUncaught(List errors, List uncaughtList) { for (UncaughtException e : uncaughtList) { errors.add(emptyStack(new UncaughtExceptionError( "Captured an uncaught exception in thread: " + e.threadName, e.error))); } } /** * Perform a thread leak check at the given scope. */ @SuppressWarnings("deprecation") protected void checkThreadLeaks( Set expectedState, List errors, LifecycleScope scope, Description description, AnnotatedElement... annotationChain) { final ThreadLeakScope annScope = firstAnnotated(ThreadLeakScope.class, annotationChain); // Return immediately if no checking. if (annScope.value() == Scope.NONE) return; // If suite scope check is requested skip testing at test level. if (annScope.value() == Scope.SUITE && scope == LifecycleScope.TEST) { return; } // Check for the set of live threads, with optional lingering. int lingerTime = firstAnnotated(ThreadLeakLingering.class, annotationChain).linger(); HashSet threads = getThreads(suiteFilters); threads.removeAll(expectedState); if (lingerTime > 0 && !threads.isEmpty()) { final long deadline = System.currentTimeMillis() + lingerTime; try { logger.warning("Will linger awaiting termination of " + threads.size() + " leaked thread(s)."); do { // Check every few hundred milliseconds until deadline occurs. We want to break out // sooner than the maximum lingerTime but there is no explicit even that // would wake us up, so poll periodically. Thread.sleep(250); threads = getThreads(suiteFilters); threads.removeAll(expectedState); if (threads.isEmpty() || System.currentTimeMillis() > deadline) break; } while (true); } catch (InterruptedException e) { logger.warning("Lingering interrupted."); } } if (threads.isEmpty()) { return; } // Take one more snapshot, this time including stack traces (costly). HashMap withTraces = getThreadsWithTraces(suiteFilters); withTraces.keySet().removeAll(expectedState); if (withTraces.isEmpty()) { return; } // Build up failure message (include stack traces of leaked threads). StringBuilder message = new StringBuilder(threads.size() + " thread" + (threads.size() == 1 ? "" : "s") + " leaked from " + scope + " scope at " + description + ": "); message.append(formatThreadStacks(withTraces)); // The first exception is leaked threads error. errors.add(RandomizedRunner.augmentStackTrace( emptyStack(new ThreadLeakError(message.toString())))); // Perform actions on leaked threads. final EnumSet actions = EnumSet.noneOf(Action.class); actions.addAll(Arrays.asList(firstAnnotated(ThreadLeakAction.class, annotationChain).value())); if (actions.contains(Action.WARN)) { logger.severe(message.toString()); } Set zombies = Collections.emptySet(); if (actions.contains(Action.INTERRUPT)) { zombies = tryToInterruptAll(errors, withTraces.keySet()); } // Process zombie thread check consequences here. if (!zombies.isEmpty()) { switch (firstAnnotated(ThreadLeakZombies.class, annotationChain).value()) { case CONTINUE: // Do nothing about it. break; case IGNORE_REMAINING_TESTS: // Mark zombie thread presence. RandomizedRunner.zombieMarker.set(true); break; default: throw new RuntimeException("Missing case."); } } } /** * Dump threads and their current stack trace. */ private String formatThreadStacks(Map threads) { StringBuilder message = new StringBuilder(); int cnt = 1; final Formatter f = new Formatter(message); for (Map.Entry e : threads.entrySet()) { f.format(Locale.ENGLISH, "\n %2d) %s", cnt++, Threads.threadName(e.getKey())).flush(); if (e.getValue().length == 0) { message.append("\n at (empty stack)"); } else { for (StackTraceElement ste : e.getValue()) { message.append("\n at ").append(ste); } } } return message.toString(); } /** Collect thread names. */ private String threadNames(Collection threads) { StringBuilder b = new StringBuilder(); final Formatter f = new Formatter(b); int cnt = 1; for (Thread t : threads) { f.format(Locale.ENGLISH, "\n %2d) %s", cnt++, Threads.threadName(t)); } return b.toString(); } /** Dump thread state. */ private String formatThreadStacksFull() { try { StringBuilder b = new StringBuilder(); b.append("\n==== jstack at approximately timeout time ====\n"); for (ThreadInfo ti : ManagementFactory.getThreadMXBean().dumpAllThreads(true, true)) { Threads.append(b, ti); } b.append("^^==============================================\n"); return b.toString(); } catch (Throwable e) { // Ignore, perhaps not available. } return formatThreadStacks(getThreadsWithTraces()); } /** * Returns all {@link ThreadLeakGroup} applicable threads, with stack * traces, for analysis. */ private HashMap getThreadsWithTraces(ThreadFilter... filters) { final Set threads = getThreads(filters); final HashMap r = new HashMap(); for (Thread t : threads) { r.put(t, t.getStackTrace()); } return r; } /** * Returns all {@link ThreadLeakGroup} threads for analysis. */ private HashSet getThreads(ThreadFilter... filters) { HashSet threads; switch (threadLeakGroup.value()) { case ALL: threads = Threads.getAllThreads(); break; case MAIN: threads = Threads.getThreads(RandomizedRunner.mainThreadGroup); break; case TESTGROUP: threads = Threads.getThreads(runner.runnerThreadGroup); break; default: throw new RuntimeException(); } final ThreadFilter filter = or(filters); for (Iterator i = threads.iterator(); i.hasNext();) { Thread t = i.next(); if (!t.isAlive() || filter.reject(t)) { i.remove(); } } return threads; } /** * Attempt to interrupt all threads in the given set. */ private Set tryToInterruptAll(List errors, Set threads) { logger.info("Starting to interrupt leaked threads:" + threadNames(threads)); // stop reporting uncaught exceptions. runner.handler.stopReporting(); try { // This means we have an unknown ordering of interrupt calls but // there is very little we can do about it, really. final HashSet ordered = new HashSet(threads); int interruptAttempts = this.killAttempts; int interruptWait = this.killWait; boolean allDead; final int restorePriority = Thread.currentThread().getPriority(); do { allDead = true; try { Thread.currentThread().setPriority(Thread.MAX_PRIORITY); for (Thread t : ordered) { t.interrupt(); } // Maximum wait time. Progress through the threads, trying to join but // decrease the join time each time. long waitDeadline = System.currentTimeMillis() + interruptWait; for (Iterator i = ordered.iterator(); i.hasNext();) { final Thread t = i.next(); if (t.isAlive()) { allDead = false; t.join(Math.max(1, waitDeadline - System.currentTimeMillis())); } else { i.remove(); } } } catch (InterruptedException e) { interruptAttempts = 0; } } while (!allDead && --interruptAttempts >= 0); Thread.currentThread().setPriority(restorePriority); // Check after the last join. HashMap zombies = new HashMap(); for (Thread t : ordered) { if (t.isAlive()) { zombies.put(t, t.getStackTrace()); } } if (zombies.isEmpty()) { logger.info("All leaked threads terminated."); } else { String message = "There are still zombie threads that couldn't be terminated:" + formatThreadStacks(zombies); logger.severe(message); errors.add(RandomizedRunner.augmentStackTrace( emptyStack(new ThreadLeakError(message.toString())))); } return zombies.keySet(); } finally { runner.handler.resumeReporting(); } } /** * Fork or not depending on the timeout value. */ boolean forkTimeoutingTask(StatementRunner r, int timeout, List errors) throws InterruptedException { if (timeout == 0) { r.run(); } else { Thread t = new Thread(r, Thread.currentThread().getName() + "-worker"); RandomizedContext.cloneFor(t); t.start(); t.join(timeout); } final boolean timedOut = !r.completed; if (r.error != null) errors.add(r.error); return timedOut; } /** * Return the {@link RunNotifier} that should be used by any sub-statements * running actual instance-scope tests. We need this because we need to * prevent spurious notifications after suite timeouts. */ RunNotifier notifier() { return subNotifier; } /** * Determine timeout for a suite. * * @return Returns timeout in milliseconds or 0 if the test should run until * finished (possibly blocking forever). */ private int determineTimeout(Class suiteClass) { TimeoutSuite timeoutAnn = suiteClass.getAnnotation(TimeoutSuite.class); return suiteTimeout.getTimeout(timeoutAnn == null ? null : timeoutAnn.millis()); } /** * Determine timeout for a single test method (candidate). * * @return Returns timeout in milliseconds or 0 if the test should run until * finished (possibly blocking forever). */ private int determineTimeout(TestCandidate c) { Integer timeout = null; Timeout timeoutAnn = c.instanceProvider.getTestClass().getAnnotation(Timeout.class); if (timeoutAnn != null) { timeout = (int) Math.min(Integer.MAX_VALUE, timeoutAnn.millis()); } // @Test annotation timeout value. Test testAnn = c.method.getAnnotation(Test.class); if (testAnn != null && testAnn.timeout() > 0) { timeout = (int) Math.min(Integer.MAX_VALUE, testAnn.timeout()); } // Method-override. timeoutAnn = c.method.getAnnotation(Timeout.class); if (timeoutAnn != null) { timeout = timeoutAnn.millis(); } return testTimeout.getTimeout(timeout); } /** * Returns an annotation's instance declared on any annotated element (first one wins) * or the default value if not present on any of them. */ private static T firstAnnotated(Class clazz, AnnotatedElement... elements) { for (AnnotatedElement element : elements) { T ann = element.getAnnotation(clazz); if (ann != null) return ann; } throw new RuntimeException("default annotation value must be within elements."); } } ThreadLeakError.java000066400000000000000000000003311235451432000375550ustar00rootroot00000000000000randomizedtesting-release-2.1.6/randomized-runner/src/main/java/com/carrotsearch/randomizedtestingpackage com.carrotsearch.randomizedtesting; /** * A thread went wild. */ @SuppressWarnings("serial") final class ThreadLeakError extends Error { public ThreadLeakError(String message) { super(message); } } Threads.java000066400000000000000000000072461235451432000361450ustar00rootroot00000000000000randomizedtesting-release-2.1.6/randomized-runner/src/main/java/com/carrotsearch/randomizedtestingpackage com.carrotsearch.randomizedtesting; import java.lang.Thread.State; import java.lang.management.LockInfo; import java.lang.management.MonitorInfo; import java.lang.management.ThreadInfo; import java.util.Arrays; import java.util.EnumMap; import java.util.HashSet; final class Threads { private Threads() {} /** * Collect thread information, JVM vendor insensitive. */ public static String threadName(Thread t) { return "Thread[" + "id=" + t.getId() + ", name=" + t.getName() + ", state=" + t.getState() + ", group=" + groupName(t.getThreadGroup()) + "]"; } private static String groupName(ThreadGroup threadGroup) { if (threadGroup == null) { return "{null group}"; } else { return threadGroup.getName(); } } private final static EnumMap lockInfoStrings; static { lockInfoStrings = new EnumMap(State.class); lockInfoStrings.put(State.BLOCKED, "blocked on "); lockInfoStrings.put(State.WAITING, "waiting on "); lockInfoStrings.put(State.TIMED_WAITING, "timed waiting on "); lockInfoStrings.put(State.TERMINATED, "terminated? on "); lockInfoStrings.put(State.RUNNABLE, "runnable? on "); lockInfoStrings.put(State.NEW, "new? on "); } /** * Dump {@link ThreadInfo} information. */ public static void append(StringBuilder b, ThreadInfo ti) { b.append('"').append(ti.getThreadName()).append('"'); b.append(" ID=").append(ti.getThreadId()); final State threadState = ti.getThreadState(); b.append(" ").append(threadState); if (ti.getLockName() != null) { b.append(" on ").append(ti.getLockName()); } if (ti.getLockOwnerName() != null) { b.append(" owned by \"").append(ti.getLockOwnerName()) .append("\" ID=").append(ti.getLockOwnerId()); } b.append(ti.isSuspended() ? " (suspended)" : ""); b.append(ti.isInNative() ? " (in native code)" : ""); b.append("\n"); final StackTraceElement[] stack = ti.getStackTrace(); final LockInfo lockInfo = ti.getLockInfo(); final MonitorInfo [] monitorInfos = ti.getLockedMonitors(); for (int i = 0; i < stack.length; i++) { b.append("\tat ").append(stack[i]).append("\n"); if (i == 0 && lockInfo != null) { b.append("\t- ") .append(lockInfoStrings.get(threadState)) .append(lockInfo) .append("\n"); } for (MonitorInfo mi : monitorInfos) { if (mi.getLockedStackDepth() == i) { b.append("\t- locked ").append(mi).append("\n"); } } } LockInfo [] lockInfos = ti.getLockedSynchronizers(); if (lockInfos.length > 0) { b.append("\tLocked synchronizers:\n"); for (LockInfo li : ti.getLockedSynchronizers()) { b.append("\t- ").append(li).append("\n"); } } b.append("\n"); } public static HashSet getAllThreads() { ThreadGroup tg = getTopThreadGroup(); return getThreads(tg); } public static HashSet getThreads(ThreadGroup tg) { Thread [] threads = new Thread [2]; int maxIndex; while ((maxIndex = tg.enumerate(threads, true)) == threads.length) { threads = new Thread [threads.length * 2]; } return new HashSet(Arrays.asList(threads).subList(0, maxIndex)); } public static ThreadGroup getTopThreadGroup() { // a lame workaround so that J9 works. ThreadGroup tg = Thread.currentThread().getThreadGroup(); while (tg != null && tg.getParent() != null) { tg = tg.getParent(); } if (tg == null) { throw new RuntimeException("No root ThreadGroup for thread: " + Thread.currentThread()); } return tg; } } TraceFormatting.java000066400000000000000000000052211235451432000376330ustar00rootroot00000000000000randomizedtesting-release-2.1.6/randomized-runner/src/main/java/com/carrotsearch/randomizedtestingpackage com.carrotsearch.randomizedtesting; import java.util.*; /** * Utilities for dealing with throwables, stacks, etc. */ public final class TraceFormatting { /** Stack filtering prefixes. */ private final List filteredPrefixes; /** * Default stack traces, no filtering. */ public TraceFormatting() { this(Collections. emptyList()); } public TraceFormatting(List filteredPrefixes) { this.filteredPrefixes = filteredPrefixes; } /** Format an exception and all of its nested stacks into a string. */ public String formatThrowable(Throwable t) { return formatThrowable(new StringBuilder(), t).toString(); } /** Format an exception and all of its nested stacks into a string. */ public StringBuilder formatThrowable(StringBuilder b, Throwable t) { b.append(t.toString()).append("\n"); formatStackTrace(b, t.getStackTrace()); if (t.getCause() != null) { b.append("Caused by: "); formatThrowable(b, t.getCause()); } return b; } /** Format a list of stack entries into a string. */ public StringBuilder formatStackTrace(StringBuilder b, StackTraceElement[] stackTrace) { return formatStackTrace(b, Arrays.asList(stackTrace)); } public String formatStackTrace(StackTraceElement[] stackTrace) { return formatStackTrace(Arrays.asList(stackTrace)); } public String formatStackTrace(Iterable stackTrace) { return formatStackTrace(new StringBuilder(), stackTrace).toString(); } /** Format a list of stack entries into a string. */ public StringBuilder formatStackTrace(StringBuilder b, Iterable stackTrace) { Set filteredSet = new HashSet(); for (StackTraceElement e : stackTrace) { String stackLine = e.toString(); String filtered = null; for (String prefix : filteredPrefixes) { if (stackLine.startsWith(prefix)) { filtered = prefix; break; } } if (filtered != null) { if (filteredSet.isEmpty()) { b.append(" [..."); } filteredSet.add(filtered); } else { appendFiltered(b, filteredSet); b.append(" ").append(stackLine).append("\n"); } } appendFiltered(b, filteredSet); return b; } private static void appendFiltered(StringBuilder b, Set filteredSet) { if (!filteredSet.isEmpty()) { boolean first = true; for (String prefix : filteredSet) { if (!first) { b.append(", "); } first = false; b.append(prefix).append("*"); } b.append("]\n"); filteredSet.clear(); } } } UncaughtExceptionError.java000066400000000000000000000004611235451432000412120ustar00rootroot00000000000000randomizedtesting-release-2.1.6/randomized-runner/src/main/java/com/carrotsearch/randomizedtestingpackage com.carrotsearch.randomizedtesting; /** * This is thrown on uncaught exceptions during suite or test execution. */ @SuppressWarnings("serial") final class UncaughtExceptionError extends Error { public UncaughtExceptionError(String message, Throwable cause) { super(message, cause); } } Validation.java000066400000000000000000000062051235451432000366370ustar00rootroot00000000000000randomizedtesting-release-2.1.6/randomized-runner/src/main/java/com/carrotsearch/randomizedtestingpackage com.carrotsearch.randomizedtesting; import java.lang.reflect.Method; import java.lang.reflect.Modifier; import java.util.Arrays; /** * Validation utilities. Chained-call style. */ final class Validation { public static final class MethodValidation { private final Method m; private String description; public MethodValidation(Method m) { this.m = m; this.description = "Method " + m.getName(); } public MethodValidation describedAs(String message) { this.description = message; return this; } public MethodValidation isPublic() { if (!Modifier.isPublic(m.getModifiers())) { throw new RuntimeException(description + " should be public."); } return this; } public MethodValidation hasArgsCount(int argsCount) { if (m.getParameterTypes().length != argsCount) { throw new RuntimeException(description + " should have " + argsCount + " parameters and" + " has these: " + Arrays.toString(m.getParameterTypes())); } return this; } public MethodValidation isStatic() { if (!Modifier.isStatic(m.getModifiers())) { throw new RuntimeException(description + " should be static."); } return this; } public MethodValidation isNotStatic() { if (Modifier.isStatic(m.getModifiers())) { throw new RuntimeException(description + " should be instance method (not static)."); } return this; } public MethodValidation hasReturnType(Class clazz) { if (!clazz.isAssignableFrom(m.getReturnType())) { throw new RuntimeException(description + " should have a return " + "type assignable to: " + clazz.getName()); } return this; } } public static final class ClassValidation { private final Class clazz; private String description; public ClassValidation(Class clazz) { this.clazz = clazz; this.description = "Class " + clazz.getName(); } public ClassValidation describedAs(String message) { this.description = message; return this; } public ClassValidation isPublic() { if (!Modifier.isPublic(clazz.getModifiers())) { throw new RuntimeException(description + " should be public."); } return this; } public ClassValidation isConcreteClass() { if (Modifier.isInterface(clazz.getModifiers())) { throw new RuntimeException(description + " should be a conrete class (not an interface)."); } if (Modifier.isAbstract(clazz.getModifiers())) { throw new RuntimeException(description + " should be a concrete class (not abstract)."); } return this; } public void hasPublicNoArgsConstructor() { try { clazz.getConstructor(new Class [0]); } catch (Throwable e) { throw new RuntimeException(description + " should have a public parameterless constructor."); } } } public static MethodValidation checkThat(Method method) { return new MethodValidation(method); } public static ClassValidation checkThat(Class clazz) { return new ClassValidation(clazz); } } 000077500000000000000000000000001235451432000362345ustar00rootroot00000000000000randomizedtesting-release-2.1.6/randomized-runner/src/main/java/com/carrotsearch/randomizedtesting/annotationsListeners.java000066400000000000000000000016051235451432000410510ustar00rootroot00000000000000randomizedtesting-release-2.1.6/randomized-runner/src/main/java/com/carrotsearch/randomizedtesting/annotationspackage com.carrotsearch.randomizedtesting.annotations; import java.lang.annotation.Documented; import java.lang.annotation.ElementType; import java.lang.annotation.Retention; import java.lang.annotation.RetentionPolicy; import java.lang.annotation.Target; import org.junit.runner.notification.RunListener; import org.junit.runner.notification.RunNotifier; import com.carrotsearch.randomizedtesting.RandomizedRunner; /** * Annotate your suite class with this annotation to automatically add hooks to * the {@link RunNotifier} used for executing tests inside * {@link RandomizedRunner}. * * @see #value() */ @Documented @Retention(RetentionPolicy.RUNTIME) @Target({ElementType.TYPE}) public @interface Listeners { /** * An array of listener classes. These classes must be instantiable (public, static, no-args * constructor, etc.). */ Class[] value(); } Name.java000066400000000000000000000005101235451432000377530ustar00rootroot00000000000000randomizedtesting-release-2.1.6/randomized-runner/src/main/java/com/carrotsearch/randomizedtesting/annotationspackage com.carrotsearch.randomizedtesting.annotations; import java.lang.annotation.*; /** * Used to annotate constructor parameters for parameterized tests. * * @see ParametersFactory */ @Documented @Retention(RetentionPolicy.RUNTIME) @Target({ElementType.PARAMETER}) public @interface Name { public String value(); } Nightly.java000066400000000000000000000017321235451432000405200ustar00rootroot00000000000000randomizedtesting-release-2.1.6/randomized-runner/src/main/java/com/carrotsearch/randomizedtesting/annotationspackage com.carrotsearch.randomizedtesting.annotations; import java.lang.annotation.Documented; import java.lang.annotation.ElementType; import java.lang.annotation.Inherited; import java.lang.annotation.Retention; import java.lang.annotation.RetentionPolicy; import java.lang.annotation.Target; import com.carrotsearch.randomizedtesting.RandomizedTest; /** * An annotation indicating a given test case (or suite) should run only during * nightly tests. * *

      The notion of "nightly" tests is based on an assumption that these tests can * take longer than usual or require more resources than usual. Nightly tests will * be most commonly used with higher scaling multipliers as in * ({@link RandomizedTest#SYSPROP_MULTIPLIER}.

      */ @Documented @Retention(RetentionPolicy.RUNTIME) @Target({ElementType.METHOD, ElementType.TYPE}) @Inherited @TestGroup(enabled = false) public @interface Nightly { /** Additional description, if needed. */ String value() default ""; } ParametersFactory.java000066400000000000000000000015561235451432000425410ustar00rootroot00000000000000randomizedtesting-release-2.1.6/randomized-runner/src/main/java/com/carrotsearch/randomizedtesting/annotationspackage com.carrotsearch.randomizedtesting.annotations; import java.lang.annotation.*; /** * Used to annotate methods providing parameters for parameterized tests. The method * annotated as the factory must be static, public, parameterless and must have a return * type assignable to {@link Iterable}<Object[]>. * *

      The iterable must return arrays conforming to the suite class's constructor * with respect to the number and types of parameters. * *

      The constructor's parameters can be annotated with {@link Name} to provide * more descriptive parameter names for test descriptions. * * @see Name */ @Documented @Retention(RetentionPolicy.RUNTIME) @Target({ElementType.METHOD}) public @interface ParametersFactory { /** * Shuffles the order of tests generated for the * parameter set. */ boolean shuffle() default true; } Repeat.java000066400000000000000000000016701235451432000403230ustar00rootroot00000000000000randomizedtesting-release-2.1.6/randomized-runner/src/main/java/com/carrotsearch/randomizedtesting/annotationspackage com.carrotsearch.randomizedtesting.annotations; import java.lang.annotation.ElementType; import java.lang.annotation.Inherited; import java.lang.annotation.Retention; import java.lang.annotation.RetentionPolicy; import java.lang.annotation.Target; /** * Repeats randomized test case a given number of times. Repetitions can * start with a different seed (predictably derived from the first one) or * start from the same seed every time (useful to check if a given test is truly * predictable for a given seed or not). */ @Retention(RetentionPolicy.RUNTIME) @Target({ElementType.METHOD, ElementType.TYPE}) @Inherited public @interface Repeat { /** * Repeat this many iterations. Must be greater or equal 1. */ int iterations() default 1; /** * Re-run all iterations with a constant seed. This may be helpful in checking * if a given test is really predictably random. */ boolean useConstantSeed() default false; }ReplicateOnEachVm.java000066400000000000000000000015321235451432000423710ustar00rootroot00000000000000randomizedtesting-release-2.1.6/randomized-runner/src/main/java/com/carrotsearch/randomizedtesting/annotationspackage com.carrotsearch.randomizedtesting.annotations; import java.lang.annotation.ElementType; import java.lang.annotation.Inherited; import java.lang.annotation.Retention; import java.lang.annotation.RetentionPolicy; import java.lang.annotation.Target; /** *

      Replicates the test class on each concurrent forked JVM. If only a single JVM * is used for running tests, this annotation has no effect.

      * *

      The purpose of this annotation is to, for example, replicate a single test suite * across multiple forked JVMs and then selectively ignore or execute tests on each * JVM, depending on its number, providing poor-man's load balancing for individual * test cases (test suites are balanced by the framework itself).

      */ @Retention(RetentionPolicy.RUNTIME) @Target({ElementType.TYPE}) @Inherited public @interface ReplicateOnEachVm {}Seed.java000066400000000000000000000031351235451432000377610ustar00rootroot00000000000000randomizedtesting-release-2.1.6/randomized-runner/src/main/java/com/carrotsearch/randomizedtesting/annotationspackage com.carrotsearch.randomizedtesting.annotations; import java.lang.annotation.Documented; import java.lang.annotation.ElementType; import java.lang.annotation.Inherited; import java.lang.annotation.Retention; import java.lang.annotation.RetentionPolicy; import java.lang.annotation.Target; import com.carrotsearch.randomizedtesting.SysGlobals; /** * Defines the starting seed for a given test or the entire suite. * *

      If applied to the * suite, it semantically overrides {@link SysGlobals#SYSPROP_RANDOM_SEED}, but * does not affect individual test cases (these should be repeatable anyway).

      * *

      If applied to the method, it overrides the default randomized value that is derived * from the global suite's seed.

      * *

      Typically, you'll want to override the class's seed to make the test repeat a "fixed" * scenario. Occasionally if there's a single failing test case for repeated tests, one * may want to override both to fix both the class's randomness and a given test case randomness. */ @Documented @Retention(RetentionPolicy.RUNTIME) @Target({ElementType.METHOD, ElementType.TYPE}) @Inherited public @interface Seed { /** * The seed expressed as a hexadecimal long number or a string random to * indicate randomized seed should be used (default value). * *

      The default value random can be used to construct a list of known * seeds for which a test previously failed and a random seed in addition to that (coverage * of previous failures + randomized run). See {@link Seeds} for more info. */ String value() default "random"; }SeedDecorators.java000066400000000000000000000020441235451432000420050ustar00rootroot00000000000000randomizedtesting-release-2.1.6/randomized-runner/src/main/java/com/carrotsearch/randomizedtesting/annotationspackage com.carrotsearch.randomizedtesting.annotations; import java.lang.annotation.*; import com.carrotsearch.randomizedtesting.SeedDecorator; /** * Allows modifying the master seed (before the suite is started). * *

      Use this annotation when you want to perturb or modify the master seed. This may be * useful if there are decisions taken in static contexts of multiple suites. In such a case * these decisions would always be identical (because at static context level the seed is * always derived from the same master). With a {@link SeedDecorator} one can perturb * the seed for every suite. * *

        *
      • Extra care should be used to make permutations consistent across different runs.
      • *
      • Seed decorators must be thread-safe, re-entrable, preferably unsynchronized and * must never fail!
      • *

      * * @see #value() */ @Documented @Retention(RetentionPolicy.RUNTIME) @Target({ElementType.TYPE}) public @interface SeedDecorators { /** * */ Class[] value(); } Seeds.java000066400000000000000000000017261235451432000401500ustar00rootroot00000000000000randomizedtesting-release-2.1.6/randomized-runner/src/main/java/com/carrotsearch/randomizedtesting/annotationspackage com.carrotsearch.randomizedtesting.annotations; import java.lang.annotation.Documented; import java.lang.annotation.ElementType; import java.lang.annotation.Inherited; import java.lang.annotation.Retention; import java.lang.annotation.RetentionPolicy; import java.lang.annotation.Target; /** * Defines a list of starting seeds for a given test. * *

      Typically, you'll want to override the class's seed to make the test repeat a "fixed" * scenario in which the test was known to fail in the past. In addition, you may still permit * a randomized seed by adding a non-restricted {@link Seed} as in: *

       * {@literal @}{@link Seeds}({
       *   {@literal @}{@link Seed}("deadbeef"),
       *   {@literal @}{@link Seed}("cafebabe"), 
       *   {@literal @}{@link Seed}()})
       * 

      */ @Documented @Retention(RetentionPolicy.RUNTIME) @Target({ElementType.METHOD}) @Inherited public @interface Seeds { /** * A non-empty array of {@link Seed}s. */ Seed [] value(); }TestGroup.java000066400000000000000000000055071235451432000410420ustar00rootroot00000000000000randomizedtesting-release-2.1.6/randomized-runner/src/main/java/com/carrotsearch/randomizedtesting/annotationspackage com.carrotsearch.randomizedtesting.annotations; import java.lang.annotation.Annotation; import java.lang.annotation.Documented; import java.lang.annotation.ElementType; import java.lang.annotation.Inherited; import java.lang.annotation.Retention; import java.lang.annotation.RetentionPolicy; import java.lang.annotation.Target; import java.util.Locale; import com.carrotsearch.randomizedtesting.RandomizedRunner; import com.carrotsearch.randomizedtesting.SysGlobals; /** * A test group applied to an annotation indicates that a given annotation * can be used on individual tests as "labels". The meaning of these labels is * mostly application-specific (example: {@link Nightly} which indicates slower, * more intensive tests that are skipped during regular runs). * *

      {@link RandomizedRunner} collects groups from all tests in a suite. A group * can be enabled or disabled using boolean system properties (or test * hooks in the code). A test case is executed if it has no groups or if all of its groups * are enabled. */ @Documented @Retention(RetentionPolicy.RUNTIME) @Target({ElementType.ANNOTATION_TYPE}) @Inherited public @interface TestGroup { /** * The name of a test group. If not defined, the default (lowercased annotation * name) is used. */ String name() default ""; /** * System property used to enable/ disable a group. If empty, a default is used: *

         * tests.name
         * 
      */ String sysProperty() default ""; /** * Is the group enabled or disabled by default (unless overridden by test group filtering * rules). */ boolean enabled() default true; /** * Utilities to deal with annotations annotated with {@link TestGroup}. */ public static class Utilities { public static String getGroupName(Class annotationClass) { TestGroup testGroup = annotationClass.getAnnotation(TestGroup.class); if (testGroup == null) throw new IllegalArgumentException("Annotation must have a @TestGroup annotation: " + annotationClass); String tmp = emptyToNull(testGroup.name()); return tmp == null ? annotationClass.getSimpleName().toLowerCase(Locale.ENGLISH) : tmp; } public static String getSysProperty(Class annotationClass) { TestGroup testGroup = annotationClass.getAnnotation(TestGroup.class); if (testGroup == null) throw new IllegalArgumentException("Annotation must have a @TestGroup annotation: " + annotationClass); String tmp = emptyToNull(testGroup.sysProperty()); return (tmp != null ? tmp : SysGlobals.prefixProperty(getGroupName(annotationClass))); } private static String emptyToNull(String value) { if (value == null || value.trim().isEmpty()) return null; return value.trim(); } } } TestMethodProviders.java000066400000000000000000000014151235451432000430560ustar00rootroot00000000000000randomizedtesting-release-2.1.6/randomized-runner/src/main/java/com/carrotsearch/randomizedtesting/annotationspackage com.carrotsearch.randomizedtesting.annotations; import java.lang.annotation.Documented; import java.lang.annotation.ElementType; import java.lang.annotation.Inherited; import java.lang.annotation.Retention; import java.lang.annotation.RetentionPolicy; import java.lang.annotation.Target; import com.carrotsearch.randomizedtesting.TestMethodProvider; /** * Test case method provider. * * TODO: it would be nice to have an _instance_ provider as opposed to method provider, * but it's hellishly difficult to integrate with the rest of the infrastructure (seeds, * repetitions, etc.). */ @Documented @Retention(RetentionPolicy.RUNTIME) @Target({ElementType.TYPE}) @Inherited public @interface TestMethodProviders { Class[] value(); } ThreadLeakAction.java000066400000000000000000000011741235451432000422440ustar00rootroot00000000000000randomizedtesting-release-2.1.6/randomized-runner/src/main/java/com/carrotsearch/randomizedtesting/annotationspackage com.carrotsearch.randomizedtesting.annotations; import java.lang.annotation.ElementType; import java.lang.annotation.Inherited; import java.lang.annotation.Retention; import java.lang.annotation.RetentionPolicy; import java.lang.annotation.Target; @Retention(RetentionPolicy.RUNTIME) @Target({ElementType.METHOD, ElementType.TYPE}) @Inherited public @interface ThreadLeakAction { public static enum Action { /** Emit a warning using Java's logging system. */ WARN, /** Try to {@link Thread#interrupt()} any leaked threads. */ INTERRUPT; }; Action [] value() default { Action.WARN, Action.INTERRUPT }; }ThreadLeakFilters.java000066400000000000000000000010171235451432000424330ustar00rootroot00000000000000randomizedtesting-release-2.1.6/randomized-runner/src/main/java/com/carrotsearch/randomizedtesting/annotationspackage com.carrotsearch.randomizedtesting.annotations; import java.lang.annotation.ElementType; import java.lang.annotation.Inherited; import java.lang.annotation.Retention; import java.lang.annotation.RetentionPolicy; import java.lang.annotation.Target; import com.carrotsearch.randomizedtesting.ThreadFilter; @Retention(RetentionPolicy.RUNTIME) @Target({ElementType.TYPE}) @Inherited public @interface ThreadLeakFilters { boolean defaultFilters() default true; Class [] filters() default {}; }ThreadLeakGroup.java000066400000000000000000000015021235451432000421160ustar00rootroot00000000000000randomizedtesting-release-2.1.6/randomized-runner/src/main/java/com/carrotsearch/randomizedtesting/annotationspackage com.carrotsearch.randomizedtesting.annotations; import java.lang.annotation.ElementType; import java.lang.annotation.Inherited; import java.lang.annotation.Retention; import java.lang.annotation.RetentionPolicy; import java.lang.annotation.Target; @Retention(RetentionPolicy.RUNTIME) @Target({ElementType.TYPE}) @Inherited public @interface ThreadLeakGroup { public static enum Group { /** * All JVM threads will be tracked. * *

      WARNING: This option will not work * on IBM J9 because of livelock bugs in {@link Thread#getAllStackTraces()}. */ ALL, /** * The "main" thread group and descendants will be tracked. */ MAIN, /** * Only per-suite test group and descendants will be tracked. */ TESTGROUP } Group value() default Group.MAIN; }ThreadLeakLingering.java000066400000000000000000000014661235451432000427510ustar00rootroot00000000000000randomizedtesting-release-2.1.6/randomized-runner/src/main/java/com/carrotsearch/randomizedtesting/annotationspackage com.carrotsearch.randomizedtesting.annotations; import java.lang.annotation.ElementType; import java.lang.annotation.Inherited; import java.lang.annotation.Retention; import java.lang.annotation.RetentionPolicy; import java.lang.annotation.Target; import java.util.Timer; import java.util.concurrent.Executors; @Retention(RetentionPolicy.RUNTIME) @Target({ElementType.METHOD, ElementType.TYPE}) @Inherited public @interface ThreadLeakLingering { /** * Time in millis to "linger" for any left-behind threads. If equals 0, there * is no waiting. * *

      * This is particularly useful if there's no way to {@link Thread#join()} and * wait for the potential forked threads to terminate. This is the case with * {@link Timer} or {@link Executors} for example. */ int linger() default 0; }ThreadLeakScope.java000066400000000000000000000016001235451432000420720ustar00rootroot00000000000000randomizedtesting-release-2.1.6/randomized-runner/src/main/java/com/carrotsearch/randomizedtesting/annotationspackage com.carrotsearch.randomizedtesting.annotations; import java.lang.annotation.ElementType; import java.lang.annotation.Inherited; import java.lang.annotation.Retention; import java.lang.annotation.RetentionPolicy; import java.lang.annotation.Target; import org.junit.ClassRule; import org.junit.Rule; @Retention(RetentionPolicy.RUNTIME) @Target({ElementType.TYPE}) @Inherited public @interface ThreadLeakScope { public static enum Scope { /** * No thread leaks from any individual test (including {@link Rule}s) or the * entire suite (including {@link ClassRule}s). */ TEST, /** * No thread leaks from entire suite scope (individual tests may leak threads, * they become part of the suite scope). */ SUITE, /** * No thread leak checks at all. Highly discouraged. */ NONE } Scope value() default Scope.TEST; }ThreadLeakZombies.java000066400000000000000000000025411235451432000424360ustar00rootroot00000000000000randomizedtesting-release-2.1.6/randomized-runner/src/main/java/com/carrotsearch/randomizedtesting/annotationspackage com.carrotsearch.randomizedtesting.annotations; import java.lang.annotation.ElementType; import java.lang.annotation.Inherited; import java.lang.annotation.Retention; import java.lang.annotation.RetentionPolicy; import java.lang.annotation.Target; @Retention(RetentionPolicy.RUNTIME) @Target({ElementType.TYPE}) @Inherited public @interface ThreadLeakZombies { public static enum Consequence { /** * Continue execution with zombie threads running in the background as if * nothing happened. This is NOT a good idea because zombie threads may be * fiddling with the test instance or static fields. It is strongly * recommended to use a combination of * {@link ThreadLeakAction.Action#INTERRUPT} together with * {@link #IGNORE_REMAINING_TESTS} to enforce interruption of leaked threads * and if this does not succeed just ignore any tests further on. *

      * For the reasons outlined above, this enum flag is marked as * {@link Deprecated}. It will be supported and will not be removed, * however. */ @Deprecated CONTINUE, /** * Ignore any remaining tests once zombie threads have been detected. See * {@link #CONTINUE} for joint use with {@link ThreadLeakAction}. */ IGNORE_REMAINING_TESTS; }; Consequence value() default Consequence.IGNORE_REMAINING_TESTS; }Timeout.java000066400000000000000000000023141235451432000405250ustar00rootroot00000000000000randomizedtesting-release-2.1.6/randomized-runner/src/main/java/com/carrotsearch/randomizedtesting/annotationspackage com.carrotsearch.randomizedtesting.annotations; import java.lang.annotation.ElementType; import java.lang.annotation.Inherited; import java.lang.annotation.Retention; import java.lang.annotation.RetentionPolicy; import java.lang.annotation.Target; import org.junit.After; import org.junit.Before; import org.junit.Test; import org.junit.rules.TestRule; import com.carrotsearch.randomizedtesting.RandomizedRunner; import com.carrotsearch.randomizedtesting.SysGlobals; /** * Maximum execution time for a single test method. Test methods are defined as * any instance-scope {@link TestRule}s, {@link Before} and {@link After} hooks * and {@link Test} methods. Suite class's constructor is not part of the * measured code (see {@link TimeoutSuite}). * *

      * Overrides a global default {@link RandomizedRunner#DEFAULT_TIMEOUT} or a * system property override {@link SysGlobals#SYSPROP_TIMEOUT}. * * @see TimeoutSuite */ @Retention(RetentionPolicy.RUNTIME) @Target({ElementType.METHOD, ElementType.TYPE}) @Inherited public @interface Timeout { /** * Timeout time in millis. The timeout time is approximate, it may take longer * to actually abort the test case. */ public int millis(); } TimeoutSuite.java000066400000000000000000000026651235451432000415500ustar00rootroot00000000000000randomizedtesting-release-2.1.6/randomized-runner/src/main/java/com/carrotsearch/randomizedtesting/annotationspackage com.carrotsearch.randomizedtesting.annotations; import java.lang.annotation.ElementType; import java.lang.annotation.Inherited; import java.lang.annotation.Retention; import java.lang.annotation.RetentionPolicy; import java.lang.annotation.Target; import org.junit.After; import org.junit.AfterClass; import org.junit.Before; import org.junit.BeforeClass; import org.junit.Test; import org.junit.rules.TestRule; import com.carrotsearch.randomizedtesting.RandomizedRunner; import com.carrotsearch.randomizedtesting.SysGlobals; /** * Maximum execution time for an entire suite (including all hooks and tests). * Suite is defined as any class-scope {@link TestRule}s, {@link BeforeClass} * and {@link AfterClass} hooks, suite class's constructor, instance-scope * {@link TestRule}s, {@link Before} and {@link After} hooks and {@link Test} * methods. * *

      * The suite class's static initializer is not part of the measured code * (if you have static initializers in your tests, get rid of them). * *

      * Overrides the global default {@link RandomizedRunner#DEFAULT_TIMEOUT} or a * system property override {@link SysGlobals#SYSPROP_TIMEOUT}. * * @see Timeout */ @Retention(RetentionPolicy.RUNTIME) @Target({ElementType.TYPE}) @Inherited public @interface TimeoutSuite { /** * Timeout time in millis. The timeout time is approximate, it may take longer * to actually abort the suite. */ public int millis(); } 000077500000000000000000000000001235451432000360505ustar00rootroot00000000000000randomizedtesting-release-2.1.6/randomized-runner/src/main/java/com/carrotsearch/randomizedtesting/generatorsASCIIGenerator.java000066400000000000000000000007151235451432000414150ustar00rootroot00000000000000randomizedtesting-release-2.1.6/randomized-runner/src/main/java/com/carrotsearch/randomizedtesting/generatorspackage com.carrotsearch.randomizedtesting.generators; /** * A generator emitting simple ASCII characters from the set * (newlines not counted): *

       * abcdefghijklmnopqrstuvwxyz
       * ABCDEFGHIJKLMNOPQRSTUVWXYZ
       * 
      */ public class ASCIIGenerator extends CodepointSetGenerator { private final static char [] ASCII_SET = "abcdefghijklmnopqrstuvwxyzABCDEFGHIJKLMNOPQRSTUVWXYZ".toCharArray(); public ASCIIGenerator() { super(ASCII_SET); } } CodepointSetGenerator.java000066400000000000000000000075711235451432000431740ustar00rootroot00000000000000randomizedtesting-release-2.1.6/randomized-runner/src/main/java/com/carrotsearch/randomizedtesting/generatorspackage com.carrotsearch.randomizedtesting.generators; import java.util.Random; /** * A string generator from a predefined set of codepoints or characters. */ public class CodepointSetGenerator extends StringGenerator { final int [] bmp; final int [] supplementary; final int [] all; /** * All characters must be from BMP (no parts of surrogate pairs allowed). */ public CodepointSetGenerator(char[] chars) { this.bmp = new int [chars.length]; this.supplementary = new int [0]; for (int i = 0; i < chars.length; i++) { bmp[i] = ((int) chars[i]) & 0xffff; if (isSurrogate(chars[i])) { throw new IllegalArgumentException("Value is part of a surrogate pair: 0x" + Integer.toHexString(bmp[i])); } } this.all = concat(bmp, supplementary); if (all.length == 0) { throw new IllegalArgumentException("Empty set of characters?"); } } /** * Parse the given {@link String} and split into BMP and supplementary codepoints. */ public CodepointSetGenerator(String s) { int bmps = 0; int supplementaries = 0; for (int i = 0; i < s.length(); i += s.offsetByCodePoints(i, 1)) { int codepoint = s.codePointAt(i); if (Character.isSupplementaryCodePoint(codepoint)) { supplementaries++; } else { bmps++; } } this.bmp = new int [bmps]; this.supplementary = new int [supplementaries]; for (int i = 0; i < s.length(); i += s.offsetByCodePoints(i, 1)) { int codepoint = s.codePointAt(i); if (Character.isSupplementaryCodePoint(codepoint)) { supplementary[--supplementaries] = codepoint; } else { bmp[--bmps] = codepoint; } } this.all = concat(bmp, supplementary); if (all.length == 0) { throw new IllegalArgumentException("Empty set of characters?"); } } @Override public String ofCodeUnitsLength(Random r, int minCodeUnits, int maxCodeUnits) { int length = RandomInts.randomIntBetween(r, minCodeUnits, maxCodeUnits); // Check and cater for odd number of code units if no bmp characters are given. if (bmp.length == 0 && isOdd(length)) { if (minCodeUnits == maxCodeUnits) { throw new IllegalArgumentException("Cannot return an odd number of code units " + " when surrogate pairs are the only available codepoints."); } else { // length is odd so we move forward or backward to the closest even number. if (length == minCodeUnits) { length++; } else { length--; } } } int [] codepoints = new int [length]; int actual = 0; while (length > 0) { if (length == 1) { codepoints[actual] = bmp[r.nextInt(bmp.length)]; } else { codepoints[actual] = all[r.nextInt(all.length)]; } if (Character.isSupplementaryCodePoint(codepoints[actual])) { length -= 2; } else { length -= 1; } actual++; } return new String(codepoints, 0, actual); } @Override public String ofCodePointsLength(Random r, int minCodePoints, int maxCodePoints) { int length = RandomInts.randomIntBetween(r, minCodePoints, maxCodePoints); int [] codepoints = new int [length]; while (length > 0) { codepoints[--length] = all[r.nextInt(all.length)]; } return new String(codepoints, 0, codepoints.length); } /** Is a given number odd? */ private boolean isOdd(int v) { return (v & 1) != 0; } private int[] concat(int[]... arrays) { int totalLength = 0; for (int[] a : arrays) totalLength += a.length; int [] concat = new int [totalLength]; for (int i = 0, j = 0; j < arrays.length;) { System.arraycopy(arrays[j], 0, concat, i, arrays[j].length); i += arrays[j].length; j++; } return concat; } private boolean isSurrogate(char chr) { return (chr >= 0xd800 && chr <= 0xdfff); } } RandomInts.java000066400000000000000000000016171235451432000407760ustar00rootroot00000000000000randomizedtesting-release-2.1.6/randomized-runner/src/main/java/com/carrotsearch/randomizedtesting/generatorspackage com.carrotsearch.randomizedtesting.generators; import java.util.Random; /** * Utility classes for random integer and integer sequences. */ public final class RandomInts { /** * A random integer from min to max (inclusive). */ public static int randomIntBetween(Random r, int min, int max) { assert max >= min : "max must be >= min: " + min + ", " + max; long range = (long) max - (long) min; if (range < Integer.MAX_VALUE) { return min + r.nextInt(1 + (int) range); } else { return min + (int) Math.round(r.nextDouble() * range); } } /** * A random integer between 0 and max (inclusive). */ public static int randomInt(Random r, int max) { if (max == 0) return 0; else if (max == Integer.MAX_VALUE) return r.nextInt() & 0x7fffffff; else return r.nextInt(max + 1); } } RandomPicks.java000066400000000000000000000024501235451432000411260ustar00rootroot00000000000000randomizedtesting-release-2.1.6/randomized-runner/src/main/java/com/carrotsearch/randomizedtesting/generatorspackage com.carrotsearch.randomizedtesting.generators; import java.util.Collection; import java.util.Iterator; import java.util.List; import java.util.Random; /** * Random selections of objects. */ public final class RandomPicks { /** * Pick a random object from the given array. */ public static T randomFrom(Random r, T [] array) { if (array.length == 0) throw new IllegalArgumentException("Can't pick a random object from an empty array."); return array[r.nextInt(array.length)]; } /** * Pick a random object from the given list. */ public static T randomFrom(Random r, List list) { if (list.size() == 0) throw new IllegalArgumentException("Can't pick a random object from an empty list."); return list.get(r.nextInt(list.size())); } /** * Pick a random object from the collection. Requires linear scanning. */ public static T randomFrom(Random r, Collection collection) { final int size = collection.size(); if (size == 0) throw new IllegalArgumentException("Can't pick a random object from an empty collection."); int pick = r.nextInt(size); T value = null; for (Iterator i = collection.iterator();; pick--) { value = i.next(); if (pick == 0) break; } return value; } } RandomStrings.java000066400000000000000000000047171235451432000415160ustar00rootroot00000000000000randomizedtesting-release-2.1.6/randomized-runner/src/main/java/com/carrotsearch/randomizedtesting/generatorspackage com.carrotsearch.randomizedtesting.generators; import java.util.Random; /** * A facade to various implementations of {@link StringGenerator} interface. */ public final class RandomStrings { public final static RealisticUnicodeGenerator realisticUnicodeGenerator = new RealisticUnicodeGenerator(); public final static UnicodeGenerator unicodeGenerator = new UnicodeGenerator(); public final static ASCIIGenerator asciiGenerator = new ASCIIGenerator(); // Ultra wide monitor required to read the source code :) public static String randomAsciiOfLengthBetween (Random r, int minCodeUnits, int maxCodeUnits) {return asciiGenerator.ofCodeUnitsLength(r, minCodeUnits, maxCodeUnits); } public static String randomAsciiOfLength (Random r, int codeUnits) {return asciiGenerator.ofCodeUnitsLength(r, codeUnits, codeUnits); } public static String randomUnicodeOfLengthBetween (Random r, int minCodeUnits, int maxCodeUnits) {return unicodeGenerator.ofCodeUnitsLength(r, minCodeUnits, maxCodeUnits); } public static String randomUnicodeOfLength (Random r, int codeUnits) {return unicodeGenerator.ofCodeUnitsLength(r, codeUnits, codeUnits); } public static String randomUnicodeOfCodepointLengthBetween (Random r, int minCodePoints, int maxCodePoints) {return unicodeGenerator.ofCodePointsLength(r, minCodePoints, maxCodePoints); } public static String randomUnicodeOfCodepointLength (Random r, int codePoints) {return unicodeGenerator.ofCodePointsLength(r, codePoints, codePoints); } public static String randomRealisticUnicodeOfLengthBetween (Random r, int minCodeUnits, int maxCodeUnits) {return realisticUnicodeGenerator.ofCodeUnitsLength(r, minCodeUnits, maxCodeUnits); } public static String randomRealisticUnicodeOfLength (Random r, int codeUnits) {return realisticUnicodeGenerator.ofCodeUnitsLength(r, codeUnits, codeUnits); } public static String randomRealisticUnicodeOfCodepointLengthBetween (Random r, int minCodePoints, int maxCodePoints) {return realisticUnicodeGenerator.ofCodePointsLength(r, minCodePoints, maxCodePoints); } public static String randomRealisticUnicodeOfCodepointLength (Random r, int codePoints) {return realisticUnicodeGenerator.ofCodePointsLength(r, codePoints, codePoints); } } RealisticUnicodeGenerator.java000066400000000000000000000115401235451432000440110ustar00rootroot00000000000000randomizedtesting-release-2.1.6/randomized-runner/src/main/java/com/carrotsearch/randomizedtesting/generatorspackage com.carrotsearch.randomizedtesting.generators; import java.util.Random; /** * A string generator that emits valid unicodeGenerator codepoints. */ public class RealisticUnicodeGenerator extends StringGenerator { /** Index-aligned with {@link #blockEnds}. */ private static final int[] blockStarts = { 0x0000, 0x0080, 0x0100, 0x0180, 0x0250, 0x02B0, 0x0300, 0x0370, 0x0400, 0x0500, 0x0530, 0x0590, 0x0600, 0x0700, 0x0750, 0x0780, 0x07C0, 0x0800, 0x0900, 0x0980, 0x0A00, 0x0A80, 0x0B00, 0x0B80, 0x0C00, 0x0C80, 0x0D00, 0x0D80, 0x0E00, 0x0E80, 0x0F00, 0x1000, 0x10A0, 0x1100, 0x1200, 0x1380, 0x13A0, 0x1400, 0x1680, 0x16A0, 0x1700, 0x1720, 0x1740, 0x1760, 0x1780, 0x1800, 0x18B0, 0x1900, 0x1950, 0x1980, 0x19E0, 0x1A00, 0x1A20, 0x1B00, 0x1B80, 0x1C00, 0x1C50, 0x1CD0, 0x1D00, 0x1D80, 0x1DC0, 0x1E00, 0x1F00, 0x2000, 0x2070, 0x20A0, 0x20D0, 0x2100, 0x2150, 0x2190, 0x2200, 0x2300, 0x2400, 0x2440, 0x2460, 0x2500, 0x2580, 0x25A0, 0x2600, 0x2700, 0x27C0, 0x27F0, 0x2800, 0x2900, 0x2980, 0x2A00, 0x2B00, 0x2C00, 0x2C60, 0x2C80, 0x2D00, 0x2D30, 0x2D80, 0x2DE0, 0x2E00, 0x2E80, 0x2F00, 0x2FF0, 0x3000, 0x3040, 0x30A0, 0x3100, 0x3130, 0x3190, 0x31A0, 0x31C0, 0x31F0, 0x3200, 0x3300, 0x3400, 0x4DC0, 0x4E00, 0xA000, 0xA490, 0xA4D0, 0xA500, 0xA640, 0xA6A0, 0xA700, 0xA720, 0xA800, 0xA830, 0xA840, 0xA880, 0xA8E0, 0xA900, 0xA930, 0xA960, 0xA980, 0xAA00, 0xAA60, 0xAA80, 0xABC0, 0xAC00, 0xD7B0, 0xE000, 0xF900, 0xFB00, 0xFB50, 0xFE00, 0xFE10, 0xFE20, 0xFE30, 0xFE50, 0xFE70, 0xFF00, 0xFFF0, 0x10000, 0x10080, 0x10100, 0x10140, 0x10190, 0x101D0, 0x10280, 0x102A0, 0x10300, 0x10330, 0x10380, 0x103A0, 0x10400, 0x10450, 0x10480, 0x10800, 0x10840, 0x10900, 0x10920, 0x10A00, 0x10A60, 0x10B00, 0x10B40, 0x10B60, 0x10C00, 0x10E60, 0x11080, 0x12000, 0x12400, 0x13000, 0x1D000, 0x1D100, 0x1D200, 0x1D300, 0x1D360, 0x1D400, 0x1F000, 0x1F030, 0x1F100, 0x1F200, 0x20000, 0x2A700, 0x2F800, 0xE0000, 0xE0100, 0xF0000, 0x100000 }; /** Index-aligned with {@link #blockStarts}. */ private static final int[] blockEnds = { 0x007F, 0x00FF, 0x017F, 0x024F, 0x02AF, 0x02FF, 0x036F, 0x03FF, 0x04FF, 0x052F, 0x058F, 0x05FF, 0x06FF, 0x074F, 0x077F, 0x07BF, 0x07FF, 0x083F, 0x097F, 0x09FF, 0x0A7F, 0x0AFF, 0x0B7F, 0x0BFF, 0x0C7F, 0x0CFF, 0x0D7F, 0x0DFF, 0x0E7F, 0x0EFF, 0x0FFF, 0x109F, 0x10FF, 0x11FF, 0x137F, 0x139F, 0x13FF, 0x167F, 0x169F, 0x16FF, 0x171F, 0x173F, 0x175F, 0x177F, 0x17FF, 0x18AF, 0x18FF, 0x194F, 0x197F, 0x19DF, 0x19FF, 0x1A1F, 0x1AAF, 0x1B7F, 0x1BBF, 0x1C4F, 0x1C7F, 0x1CFF, 0x1D7F, 0x1DBF, 0x1DFF, 0x1EFF, 0x1FFF, 0x206F, 0x209F, 0x20CF, 0x20FF, 0x214F, 0x218F, 0x21FF, 0x22FF, 0x23FF, 0x243F, 0x245F, 0x24FF, 0x257F, 0x259F, 0x25FF, 0x26FF, 0x27BF, 0x27EF, 0x27FF, 0x28FF, 0x297F, 0x29FF, 0x2AFF, 0x2BFF, 0x2C5F, 0x2C7F, 0x2CFF, 0x2D2F, 0x2D7F, 0x2DDF, 0x2DFF, 0x2E7F, 0x2EFF, 0x2FDF, 0x2FFF, 0x303F, 0x309F, 0x30FF, 0x312F, 0x318F, 0x319F, 0x31BF, 0x31EF, 0x31FF, 0x32FF, 0x33FF, 0x4DBF, 0x4DFF, 0x9FFF, 0xA48F, 0xA4CF, 0xA4FF, 0xA63F, 0xA69F, 0xA6FF, 0xA71F, 0xA7FF, 0xA82F, 0xA83F, 0xA87F, 0xA8DF, 0xA8FF, 0xA92F, 0xA95F, 0xA97F, 0xA9DF, 0xAA5F, 0xAA7F, 0xAADF, 0xABFF, 0xD7AF, 0xD7FF, 0xF8FF, 0xFAFF, 0xFB4F, 0xFDFF, 0xFE0F, 0xFE1F, 0xFE2F, 0xFE4F, 0xFE6F, 0xFEFF, 0xFFEF, 0xFFFF, 0x1007F, 0x100FF, 0x1013F, 0x1018F, 0x101CF, 0x101FF, 0x1029F, 0x102DF, 0x1032F, 0x1034F, 0x1039F, 0x103DF, 0x1044F, 0x1047F, 0x104AF, 0x1083F, 0x1085F, 0x1091F, 0x1093F, 0x10A5F, 0x10A7F, 0x10B3F, 0x10B5F, 0x10B7F, 0x10C4F, 0x10E7F, 0x110CF, 0x123FF, 0x1247F, 0x1342F, 0x1D0FF, 0x1D1FF, 0x1D24F, 0x1D35F, 0x1D37F, 0x1D7FF, 0x1F02F, 0x1F09F, 0x1F1FF, 0x1F2FF, 0x2A6DF, 0x2B73F, 0x2FA1F, 0xE007F, 0xE01EF, 0xFFFFF, 0x10FFFF }; @Override public String ofCodeUnitsLength(Random r, int minCodeUnits, int maxCodeUnits) { int length = RandomInts.randomIntBetween(r, minCodeUnits, minCodeUnits); final int block = r.nextInt(blockStarts.length); final StringBuilder sb = new StringBuilder(); while (length > 0) { int cp = RandomInts.randomIntBetween(r, blockStarts[block], blockEnds[block]); if (length > Character.charCount(cp)) { sb.appendCodePoint(cp); length -= Character.charCount(cp); } else { // Padding for blocks that don't fit. sb.appendCodePoint('a'); length--; } } return sb.toString(); } @Override public String ofCodePointsLength(Random r, int minCodePoints, int maxCodePoints) { final int length = RandomInts.randomIntBetween(r, minCodePoints, maxCodePoints); final int block = r.nextInt(blockStarts.length); final StringBuilder sb = new StringBuilder(); for (int i = 0; i < length; i++) sb.appendCodePoint(RandomInts.randomIntBetween(r, blockStarts[block], blockEnds[block])); return sb.toString(); } } StringGenerator.java000066400000000000000000000037441235451432000420400ustar00rootroot00000000000000randomizedtesting-release-2.1.6/randomized-runner/src/main/java/com/carrotsearch/randomizedtesting/generatorspackage com.carrotsearch.randomizedtesting.generators; import java.util.Random; /** * A {@link StringGenerator} generates random strings composed of characters. What these characters * are and their distribution depends on a subclass. * * @see String */ public abstract class StringGenerator { /** * An alias for {@link #ofCodeUnitsLength(Random, int, int)}. */ public String ofStringLength(Random r, int minCodeUnits, int maxCodeUnits) { return ofCodeUnitsLength(r, minCodeUnits, maxCodeUnits); } /** * @return Returns a string of variable length between minCodeUnits (inclusive) * and maxCodeUnits (inclusive) length. Code units are essentially * an equivalent of char type, see {@link String} class for * explanation. * * @param minCodeUnits Minimum number of code units (inclusive). * @param maxCodeUnits Maximum number of code units (inclusive). * @throws IllegalArgumentException Thrown if the generator cannot emit random string * of the given unit length. For example a generator emitting only extended unicodeGenerator * plane characters (encoded as surrogate pairs) will not be able to emit an odd number * of code units. */ public abstract String ofCodeUnitsLength(Random r, int minCodeUnits, int maxCodeUnits); /** * @return Returns a string of variable length between minCodePoints (inclusive) * and maxCodePoints (inclusive) length. Code points are full unicodeGenerator * codepoints or an equivalent of int type, see {@link String} class for * explanation. The returned {@link String#length()} may exceed maxCodeUnits * because certain code points may be encoded as surrogate pairs. * * @param minCodePoints Minimum number of code points (inclusive). * @param maxCodePoints Maximum number of code points (inclusive). */ public abstract String ofCodePointsLength(Random r, int minCodePoints, int maxCodePoints); } UnicodeGenerator.java000066400000000000000000000066511235451432000421600ustar00rootroot00000000000000randomizedtesting-release-2.1.6/randomized-runner/src/main/java/com/carrotsearch/randomizedtesting/generatorspackage com.carrotsearch.randomizedtesting.generators; import java.util.Random; /** * A string generator that emits valid unicodeGenerator codepoints. */ public class UnicodeGenerator extends StringGenerator { private final static int SURROGATE_RANGE = Character.MAX_SURROGATE - Character.MIN_SURROGATE + 1; private final static int CODEPOINT_RANGE = Character.MAX_CODE_POINT - SURROGATE_RANGE; @Override public String ofCodeUnitsLength(Random r, int minCodeUnits, int maxCodeUnits) { int length = RandomInts.randomIntBetween(r, minCodeUnits, maxCodeUnits); char [] chars = new char [length]; for (int i = 0; i < chars.length;) { final int t = RandomInts.randomIntBetween(r, 0, 4); if (t == 0 && i < length - 1) { // Make a surrogate pair chars[i++] = (char) RandomInts.randomIntBetween(r, 0xd800, 0xdbff); // high chars[i++] = (char) RandomInts.randomIntBetween(r, 0xdc00, 0xdfff); // low } else if (t <= 1) { chars[i++] = (char) RandomInts.randomIntBetween(r, 0, 0x007f); } else if (t == 2) { chars[i++] = (char) RandomInts.randomIntBetween(r, 0x80, 0x07ff); } else if (t == 3) { chars[i++] = (char) RandomInts.randomIntBetween(r, 0x800, 0xd7ff); } else if (t == 4) { chars[i++] = (char) RandomInts.randomIntBetween(r, 0xe000, 0xffff); } } return new String(chars); } @Override public String ofCodePointsLength(Random r, int minCodePoints, int maxCodePoints) { int length = RandomInts.randomIntBetween(r, minCodePoints, maxCodePoints); int [] chars = new int [length]; for (int i = 0; i < chars.length; i++) { int v = RandomInts.randomIntBetween(r, 0, CODEPOINT_RANGE); if (v >= Character.MIN_SURROGATE) v += SURROGATE_RANGE; chars[i] = v; } return new String(chars, 0, chars.length); } /** * Returns a random string that will have a random UTF-8 representation length between * minUtf8Length and maxUtf8Length. * * @param minUtf8Length Minimum UTF-8 representation length (inclusive). * @param maxUtf8Length Maximum UTF-8 representation length (inclusive). */ public String ofUtf8Length(Random r, int minUtf8Length, int maxUtf8Length) { final int length = RandomInts.randomIntBetween(r, minUtf8Length, maxUtf8Length); final char[] buffer = new char [length * 3]; int bytes = length; int i = 0; for (; i < buffer.length && bytes != 0; i++) { int t; if (bytes >= 4) { t = r.nextInt(5); } else if (bytes >= 3) { t = r.nextInt(4); } else if (bytes >= 2) { t = r.nextInt(2); } else { t = 0; } if (t == 0) { buffer[i] = (char) RandomInts.randomIntBetween(r, 0, 0x7f); bytes--; } else if (1 == t) { buffer[i] = (char) RandomInts.randomIntBetween(r, 0x80, 0x7ff); bytes -= 2; } else if (2 == t) { buffer[i] = (char) RandomInts.randomIntBetween(r, 0x800, 0xd7ff); bytes -= 3; } else if (3 == t) { buffer[i] = (char) RandomInts.randomIntBetween(r, 0xe000, 0xffff); bytes -= 3; } else if (4 == t) { // Make a surrogate pair buffer[i++] = (char) RandomInts.randomIntBetween(r, 0xd800, 0xdbff); // high buffer[i] = (char) RandomInts.randomIntBetween(r, 0xdc00, 0xdfff); // low bytes -= 4; } } return new String(buffer, 0, i); } } 000077500000000000000000000000001235451432000357075ustar00rootroot00000000000000randomizedtesting-release-2.1.6/randomized-runner/src/main/java/com/carrotsearch/randomizedtesting/listenersReproduceInfoPrinter.java000066400000000000000000000027011235451432000426620ustar00rootroot00000000000000randomizedtesting-release-2.1.6/randomized-runner/src/main/java/com/carrotsearch/randomizedtesting/listenerspackage com.carrotsearch.randomizedtesting.listeners; import org.junit.internal.AssumptionViolatedException; import org.junit.runner.Description; import org.junit.runner.notification.Failure; import org.junit.runner.notification.RunListener; import com.carrotsearch.randomizedtesting.*; /** * A {@link RunListener} that emits to {@link System#err} a string with command * line parameters allowing quick test re-run under ANT command line. */ public class ReproduceInfoPrinter extends RunListener { @Override public void testFailure(Failure failure) throws Exception { // Ignore assumptions. if (failure.getException() instanceof AssumptionViolatedException) { return; } final Description d = failure.getDescription(); final StringBuilder b = new StringBuilder(); b.append("FAILURE : ").append(d.getDisplayName()).append("\n"); b.append("Message : " + failure.getMessage() + "\n"); b.append("Reproduce: "); new ReproduceErrorMessageBuilder(b).appendAllOpts(failure.getDescription()); b.append("\n"); b.append("Throwable:\n"); if (failure.getException() != null) { TraceFormatting traces = new TraceFormatting(); try { traces = RandomizedContext.current().getRunner().getTraceFormatting(); } catch (IllegalStateException e) { // Ignore if no context. } traces.formatThrowable(b, failure.getException()); } System.err.println(b.toString()); } } package.html000066400000000000000000000027771235451432000361750ustar00rootroot00000000000000randomizedtesting-release-2.1.6/randomized-runner/src/main/java/com/carrotsearch/randomizedtesting Randomized Testing: Randomized Runner Provides {@link com.carrotsearch.randomizedtesting.RandomizedRunner}: randomized tests under control and more.

      Inspired by the Apache Lucene project's infrastructure, this project brings a refactored, stand-alone runner for JUnit 4.x tests, which encapsulates built-in repeatable randomized tests, threading and timeout control, parameter factories, thread execution groups and more. Everything is JUnit compatible and will work in your favorite IDE.

      {@link com.carrotsearch.randomizedtesting.RandomizedRunner} provides a {@link org.junit.runner.Runner} implementation for JUnit's {@link org.junit.runner.RunWith} annotation.

      Core classes to look at:

      • {@link com.carrotsearch.randomizedtesting.RandomizedRunner}
      • {@link com.carrotsearch.randomizedtesting.RandomizedTest}
      • {@link com.carrotsearch.randomizedtesting.annotations.ParametersFactory}

      Examples of use and more resources can be found at: Carrot Search labs site.

      000077500000000000000000000000001235451432000350315ustar00rootroot00000000000000randomizedtesting-release-2.1.6/randomized-runner/src/main/java/com/carrotsearch/randomizedtesting/rulesNoClassHooksShadowingRule.java000066400000000000000000000024161235451432000427410ustar00rootroot00000000000000randomizedtesting-release-2.1.6/randomized-runner/src/main/java/com/carrotsearch/randomizedtesting/rulespackage com.carrotsearch.randomizedtesting.rules; /* * Licensed to the Apache Software Foundation (ASF) under one or more * contributor license agreements. See the NOTICE file distributed with * this work for additional information regarding copyright ownership. * The ASF licenses this file to You under the Apache License, Version 2.0 * (the "License"); you may not use this file except in compliance with * the License. You may obtain a copy of the License at * * http://www.apache.org/licenses/LICENSE-2.0 * * Unless required by applicable law or agreed to in writing, software * distributed under the License is distributed on an "AS IS" BASIS, * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. * See the License for the specific language governing permissions and * limitations under the License. */ import org.junit.AfterClass; import org.junit.BeforeClass; /** * Don't allow {@link BeforeClass} and {@link AfterClass} hook shadowing as it is most * likely a user error. JUnit rules for shadowed hook methods are weird. */ public class NoClassHooksShadowingRule extends NoShadowingOrOverridesOnMethodsRule { @SuppressWarnings("unchecked") public NoClassHooksShadowingRule() { super(BeforeClass.class, AfterClass.class); } } NoInstanceHooksOverridesRule.java000066400000000000000000000024331235451432000434560ustar00rootroot00000000000000randomizedtesting-release-2.1.6/randomized-runner/src/main/java/com/carrotsearch/randomizedtesting/rulespackage com.carrotsearch.randomizedtesting.rules; /* * Licensed to the Apache Software Foundation (ASF) under one or more * contributor license agreements. See the NOTICE file distributed with * this work for additional information regarding copyright ownership. * The ASF licenses this file to You under the Apache License, Version 2.0 * (the "License"); you may not use this file except in compliance with * the License. You may obtain a copy of the License at * * http://www.apache.org/licenses/LICENSE-2.0 * * Unless required by applicable law or agreed to in writing, software * distributed under the License is distributed on an "AS IS" BASIS, * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. * See the License for the specific language governing permissions and * limitations under the License. */ import org.junit.After; import org.junit.Before; /** * Don't allow {@link Before} and {@link After} hook overrides as it is most * likely a user error and will result in superclass methods not being called * (requires manual chaining). */ public class NoInstanceHooksOverridesRule extends NoShadowingOrOverridesOnMethodsRule { @SuppressWarnings("unchecked") public NoInstanceHooksOverridesRule() { super(Before.class, After.class); } } NoShadowingOrOverridesOnMethodsRule.java000066400000000000000000000056731235451432000447640ustar00rootroot00000000000000randomizedtesting-release-2.1.6/randomized-runner/src/main/java/com/carrotsearch/randomizedtesting/rulespackage com.carrotsearch.randomizedtesting.rules; import java.lang.annotation.Annotation; import java.lang.reflect.Method; import java.util.Map; import org.junit.rules.TestRule; import org.junit.runner.Description; import org.junit.runners.model.Statement; import com.carrotsearch.randomizedtesting.ClassModel; import com.carrotsearch.randomizedtesting.RandomizedContext; import com.carrotsearch.randomizedtesting.ClassModel.MethodModel; /** * Discovers shadowing or override relationships among methods annotated with any of the * provided annotations. */ public abstract class NoShadowingOrOverridesOnMethodsRule implements TestRule { private Class[] annotations; public NoShadowingOrOverridesOnMethodsRule(Class... annotations) { this.annotations = annotations; } @Override public final Statement apply(final Statement base, final Description description) { return new Statement() { @Override public void evaluate() throws Throwable { Class testClass; try { testClass = RandomizedContext.current().getTargetClass(); } catch (Throwable t) { testClass = description.getTestClass(); } validate(testClass); base.evaluate(); } }; } public final void validate(Class clazz) throws Throwable { ClassModel classModel = new ClassModel(clazz); for (Class annClass : annotations) { checkNoShadowsOrOverrides(clazz, classModel, annClass); } } private void checkNoShadowsOrOverrides(Class clazz, ClassModel classModel, Class ann) { Map annotatedLeafMethods = classModel.getAnnotatedLeafMethods(ann); StringBuilder b = new StringBuilder(); for (Map.Entry e : annotatedLeafMethods.entrySet()) { if (verify(e.getKey())) { MethodModel mm = e.getValue(); if (mm.getDown() != null || mm.getUp() != null) { b.append("Methods annotated with @" + ann.getName() + " shadow or override each other:\n"); while (mm.getUp() != null) { mm = mm.getUp(); } while (mm != null) { b.append(" - "); if (mm.element.isAnnotationPresent(ann)) b.append("@").append(ann.getSimpleName()).append(" "); b.append(signature(mm.element)).append("\n"); mm = mm.getDown(); } } } } if (b.length() > 0) { throw new RuntimeException("There are overridden methods annotated with " + ann.getName() + ". These methods would not be executed by JUnit and need to manually chain themselves which can lead to" + " maintenance problems. Consider using different method names or make hook methods private.\n" + b.toString().trim()); } } protected boolean verify(Method key) { return true; } private String signature(Method m) { return m.toString(); } } RamUsageEstimator.java000066400000000000000000000767631235451432000413130ustar00rootroot00000000000000randomizedtesting-release-2.1.6/randomized-runner/src/main/java/com/carrotsearch/randomizedtesting/rules /* * Imported from java-sizeof project. */ package com.carrotsearch.randomizedtesting.rules; /** * Licensed to the Apache Software Foundation (ASF) under one or more * contributor license agreements. See the NOTICE file distributed with * this work for additional information regarding copyright ownership. * The ASF licenses this file to You under the Apache License, Version 2.0 * (the "License"); you may not use this file except in compliance with * the License. You may obtain a copy of the License at * * http://www.apache.org/licenses/LICENSE-2.0 * * Unless required by applicable law or agreed to in writing, software * distributed under the License is distributed on an "AS IS" BASIS, * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. * See the License for the specific language governing permissions and * limitations under the License. */ import java.lang.management.ManagementFactory; import java.lang.reflect.Array; import java.lang.reflect.Field; import java.lang.reflect.InvocationTargetException; import java.lang.reflect.Method; import java.lang.reflect.Modifier; import java.text.DecimalFormat; import java.text.DecimalFormatSymbols; import java.util.*; /** * Estimates the size (memory representation) of Java objects. * * @see #sizeOf(Object) * @see #shallowSizeOf(Object) * @see #shallowSizeOfInstance(Class) */ final class RamUsageEstimator { /** * JVM diagnostic features. */ public static enum JvmFeature { OBJECT_REFERENCE_SIZE("Object reference size estimated using array index scale."), ARRAY_HEADER_SIZE("Array header size estimated using array based offset."), FIELD_OFFSETS("Shallow instance size based on field offsets."), OBJECT_ALIGNMENT("Object alignment retrieved from HotSpotDiagnostic MX bean."); public final String description; private JvmFeature(String description) { this.description = description; } @Override public String toString() { return super.name() + " (" + description + ")"; } } /** JVM info string for debugging and reports. */ public final static String JVM_INFO_STRING; /** One kilobyte bytes. */ public static final long ONE_KB = 1024; /** One megabyte bytes. */ public static final long ONE_MB = ONE_KB * ONE_KB; /** One gigabyte bytes.*/ public static final long ONE_GB = ONE_KB * ONE_MB; /** No instantiation. */ private RamUsageEstimator() {} public final static int NUM_BYTES_BOOLEAN = 1; public final static int NUM_BYTES_BYTE = 1; public final static int NUM_BYTES_CHAR = 2; public final static int NUM_BYTES_SHORT = 2; public final static int NUM_BYTES_INT = 4; public final static int NUM_BYTES_FLOAT = 4; public final static int NUM_BYTES_LONG = 8; public final static int NUM_BYTES_DOUBLE = 8; /** * Number of bytes this jvm uses to represent an object reference. */ public final static int NUM_BYTES_OBJECT_REF; /** * Number of bytes to represent an object header (no fields, no alignments). */ public final static int NUM_BYTES_OBJECT_HEADER; /** * Number of bytes to represent an array header (no content, but with alignments). */ public final static int NUM_BYTES_ARRAY_HEADER; /** * A constant specifying the object alignment boundary inside the JVM. Objects will * always take a full multiple of this constant, possibly wasting some space. */ public final static int NUM_BYTES_OBJECT_ALIGNMENT; /** * Sizes of primitive classes. */ private static final Map,Integer> primitiveSizes; static { primitiveSizes = new IdentityHashMap,Integer>(); primitiveSizes.put(boolean.class, NUM_BYTES_BOOLEAN); primitiveSizes.put(byte.class, NUM_BYTES_BYTE); primitiveSizes.put(char.class, NUM_BYTES_CHAR); primitiveSizes.put(short.class, NUM_BYTES_SHORT); primitiveSizes.put(int.class, NUM_BYTES_INT); primitiveSizes.put(float.class, NUM_BYTES_FLOAT); primitiveSizes.put(double.class, NUM_BYTES_DOUBLE); primitiveSizes.put(long.class, NUM_BYTES_LONG); } /** * A handle to sun.misc.Unsafe. */ private final static Object theUnsafe; /** * A handle to sun.misc.Unsafe#fieldOffset(Field). */ private final static Method objectFieldOffsetMethod; /** * All the supported "internal" JVM features detected at clinit. */ private final static EnumSet supportedFeatures; /** * Initialize constants and try to collect information about the JVM internals. */ static { // Initialize empirically measured defaults. We'll modify them to the current // JVM settings later on if possible. int referenceSize = Constants.JRE_IS_64BIT ? 8 : 4; int objectHeader = Constants.JRE_IS_64BIT ? 16 : 8; // The following is objectHeader + NUM_BYTES_INT, but aligned (object alignment) // so on 64 bit JVMs it'll be align(16 + 4, @8) = 24. int arrayHeader = Constants.JRE_IS_64BIT ? 24 : 12; supportedFeatures = EnumSet.noneOf(JvmFeature.class); Class unsafeClass = null; Object tempTheUnsafe = null; try { unsafeClass = Class.forName("sun.misc.Unsafe"); final Field unsafeField = unsafeClass.getDeclaredField("theUnsafe"); unsafeField.setAccessible(true); tempTheUnsafe = unsafeField.get(null); } catch (Exception e) { // Ignore. } theUnsafe = tempTheUnsafe; // get object reference size by getting scale factor of Object[] arrays: try { final Method arrayIndexScaleM = unsafeClass.getMethod("arrayIndexScale", Class.class); referenceSize = ((Number) arrayIndexScaleM.invoke(theUnsafe, Object[].class)).intValue(); supportedFeatures.add(JvmFeature.OBJECT_REFERENCE_SIZE); } catch (Exception e) { // ignore. } // "best guess" based on reference size. We will attempt to modify // these to exact values if there is supported infrastructure. objectHeader = Constants.JRE_IS_64BIT ? (8 + referenceSize) : 8; arrayHeader = Constants.JRE_IS_64BIT ? (8 + 2 * referenceSize) : 12; // get the object header size: // - first try out if the field offsets are not scaled (see warning in Unsafe docs) // - get the object header size by getting the field offset of the first field of a dummy object // If the scaling is byte-wise and unsafe is available, enable dynamic size measurement for // estimateRamUsage(). Method tempObjectFieldOffsetMethod = null; try { final Method objectFieldOffsetM = unsafeClass.getMethod("objectFieldOffset", Field.class); final Field dummy1Field = DummyTwoLongObject.class.getDeclaredField("dummy1"); final int ofs1 = ((Number) objectFieldOffsetM.invoke(theUnsafe, dummy1Field)).intValue(); final Field dummy2Field = DummyTwoLongObject.class.getDeclaredField("dummy2"); final int ofs2 = ((Number) objectFieldOffsetM.invoke(theUnsafe, dummy2Field)).intValue(); if (Math.abs(ofs2 - ofs1) == NUM_BYTES_LONG) { final Field baseField = DummyOneFieldObject.class.getDeclaredField("base"); objectHeader = ((Number) objectFieldOffsetM.invoke(theUnsafe, baseField)).intValue(); supportedFeatures.add(JvmFeature.FIELD_OFFSETS); tempObjectFieldOffsetMethod = objectFieldOffsetM; } } catch (Exception e) { // Ignore. } objectFieldOffsetMethod = tempObjectFieldOffsetMethod; // Get the array header size by retrieving the array base offset // (offset of the first element of an array). try { final Method arrayBaseOffsetM = unsafeClass.getMethod("arrayBaseOffset", Class.class); // we calculate that only for byte[] arrays, it's actually the same for all types: arrayHeader = ((Number) arrayBaseOffsetM.invoke(theUnsafe, byte[].class)).intValue(); supportedFeatures.add(JvmFeature.ARRAY_HEADER_SIZE); } catch (Exception e) { // Ignore. } NUM_BYTES_OBJECT_REF = referenceSize; NUM_BYTES_OBJECT_HEADER = objectHeader; NUM_BYTES_ARRAY_HEADER = arrayHeader; // Try to get the object alignment (the default seems to be 8 on Hotspot, // regardless of the architecture). int objectAlignment = 8; try { final Class beanClazz = Class.forName("com.sun.management.HotSpotDiagnosticMXBean"); // Try to get the diagnostic mxbean without calling {@link ManagementFactory#getPlatformMBeanServer()} // which starts AWT thread (and shows junk in the dock) on a Mac: Object hotSpotBean; // Java 7+, HotSpot try { hotSpotBean = ManagementFactory.class .getMethod("getPlatformMXBean", Class.class) .invoke(null, beanClazz); } catch (Exception e1) { // Java 6, HotSpot try { Class sunMF = Class.forName("sun.management.ManagementFactory"); hotSpotBean = sunMF.getMethod("getDiagnosticMXBean").invoke(null); } catch (Exception e2) { // Last resort option is an attempt to get it from ManagementFactory's server anyway (may start AWT). hotSpotBean = ManagementFactory.newPlatformMXBeanProxy( ManagementFactory.getPlatformMBeanServer(), "com.sun.management:type=HotSpotDiagnostic", beanClazz); } } if (hotSpotBean != null) { final Method getVMOptionMethod = beanClazz.getMethod("getVMOption", String.class); final Object vmOption = getVMOptionMethod.invoke(hotSpotBean, "ObjectAlignmentInBytes"); objectAlignment = Integer.parseInt( vmOption.getClass().getMethod("getValue").invoke(vmOption).toString()); supportedFeatures.add(JvmFeature.OBJECT_ALIGNMENT); } } catch (Exception e) { // Ignore. } NUM_BYTES_OBJECT_ALIGNMENT = objectAlignment; JVM_INFO_STRING = "[JVM: " + Constants.JVM_NAME + ", " + Constants.JVM_VERSION + ", " + Constants.JVM_VENDOR + ", " + Constants.JAVA_VENDOR + ", " + Constants.JAVA_VERSION + "]"; } /** * Cached information about a given class. */ private static final class ClassCache { public final long alignedShallowInstanceSize; public final Field[] referenceFields; public ClassCache(long alignedShallowInstanceSize, Field[] referenceFields) { this.alignedShallowInstanceSize = alignedShallowInstanceSize; this.referenceFields = referenceFields; } } // Object with just one field to determine the object header size by getting the offset of the dummy field: @SuppressWarnings("unused") private static final class DummyOneFieldObject { public byte base; } // Another test object for checking, if the difference in offsets of dummy1 and dummy2 is 8 bytes. // Only then we can be sure that those are real, unscaled offsets: @SuppressWarnings("unused") private static final class DummyTwoLongObject { public long dummy1, dummy2; } /** * Returns true, if the current JVM is fully supported by {@code RamUsageEstimator}. * If this method returns {@code false} you are maybe using a 3rd party Java VM * that is not supporting Oracle/Sun private APIs. The memory estimates can be * imprecise then (no way of detecting compressed references, alignments, etc.). * Lucene still tries to use sensible defaults. */ public static boolean isSupportedJVM() { return supportedFeatures.size() == JvmFeature.values().length; } /** * Aligns an object size to be the next multiple of {@link #NUM_BYTES_OBJECT_ALIGNMENT}. */ public static long alignObjectSize(long size) { size += (long) NUM_BYTES_OBJECT_ALIGNMENT - 1L; return size - (size % NUM_BYTES_OBJECT_ALIGNMENT); } /** Returns the size in bytes of the byte[] object. */ public static long sizeOf(byte[] arr) { return alignObjectSize((long) NUM_BYTES_ARRAY_HEADER + arr.length); } /** Returns the size in bytes of the boolean[] object. */ public static long sizeOf(boolean[] arr) { return alignObjectSize((long) NUM_BYTES_ARRAY_HEADER + arr.length); } /** Returns the size in bytes of the char[] object. */ public static long sizeOf(char[] arr) { return alignObjectSize((long) NUM_BYTES_ARRAY_HEADER + (long) NUM_BYTES_CHAR * arr.length); } /** Returns the size in bytes of the short[] object. */ public static long sizeOf(short[] arr) { return alignObjectSize((long) NUM_BYTES_ARRAY_HEADER + (long) NUM_BYTES_SHORT * arr.length); } /** Returns the size in bytes of the int[] object. */ public static long sizeOf(int[] arr) { return alignObjectSize((long) NUM_BYTES_ARRAY_HEADER + (long) NUM_BYTES_INT * arr.length); } /** Returns the size in bytes of the float[] object. */ public static long sizeOf(float[] arr) { return alignObjectSize((long) NUM_BYTES_ARRAY_HEADER + (long) NUM_BYTES_FLOAT * arr.length); } /** Returns the size in bytes of the long[] object. */ public static long sizeOf(long[] arr) { return alignObjectSize((long) NUM_BYTES_ARRAY_HEADER + (long) NUM_BYTES_LONG * arr.length); } /** Returns the size in bytes of the double[] object. */ public static long sizeOf(double[] arr) { return alignObjectSize((long) NUM_BYTES_ARRAY_HEADER + (long) NUM_BYTES_DOUBLE * arr.length); } /** * Estimates the RAM usage by the given object. It will * walk the object tree and sum up all referenced objects. * *

      Resource Usage: This method internally uses a set of * every object seen during traversals so it does allocate memory * (it isn't side-effect free). After the method exits, this memory * should be GCed.

      */ public static long sizeOf(Object obj) { ArrayList stack = new ArrayList(); stack.add(obj); return measureSizeOf(stack); } /** * Same as {@link #sizeOf(Object)} but sums up all the arguments. Not an * overload to prevent accidental parameter conflicts with {@link #sizeOf(Object)}. */ public static long sizeOfAll(Object... objects) { return sizeOfAll(Arrays.asList(objects)); } /** * Same as {@link #sizeOf(Object)} but sums up all the arguments. Not an * overload to prevent accidental parameter conflicts with {@link #sizeOf(Object)}. */ public static long sizeOfAll(Iterable objects) { final ArrayList stack; if (objects instanceof Collection) { stack = new ArrayList(((Collection) objects).size()); } else { stack = new ArrayList(); } for (Object o : objects) { stack.add(o); } return measureSizeOf(stack); } /** * Estimates a "shallow" memory usage of the given object. For arrays, this will be the * memory taken by array storage (no subreferences will be followed). For objects, this * will be the memory taken by the fields. * * JVM object alignments are also applied. */ public static long shallowSizeOf(Object obj) { if (obj == null) return 0; final Class clz = obj.getClass(); if (clz.isArray()) { return shallowSizeOfArray(obj); } else { return shallowSizeOfInstance(clz); } } /** * Same as {@link #shallowSizeOf(Object)} but sums up all the arguments. Not an * overload to prevent accidental parameter conflicts with {@link #shallowSizeOf(Object)}. */ public static long shallowSizeOfAll(Object... objects) { return shallowSizeOfAll(Arrays.asList(objects)); } /** * Same as {@link #shallowSizeOf(Object)} but sums up all the arguments. Duplicate * objects are not resolved and will be counted twice. * Not an overload to prevent accidental parameter conflicts with * {@link #shallowSizeOf(Object)}. */ public static long shallowSizeOfAll(Iterable objects) { long sum = 0; for (Object o : objects) { sum += shallowSizeOf(o); } return sum; } /** * Returns the shallow instance size in bytes an instance of the given class would occupy. * This works with all conventional classes and primitive types, but not with arrays * (the size then depends on the number of elements and varies from object to object). * * @see #shallowSizeOf(Object) * @throws IllegalArgumentException if {@code clazz} is an array class. */ public static long shallowSizeOfInstance(Class clazz) { if (clazz.isArray()) throw new IllegalArgumentException("This method does not work with array classes."); if (clazz.isPrimitive()) return primitiveSizes.get(clazz); long size = NUM_BYTES_OBJECT_HEADER; // Walk type hierarchy for (;clazz != null; clazz = clazz.getSuperclass()) { final Field[] fields = clazz.getDeclaredFields(); for (Field f : fields) { if (!Modifier.isStatic(f.getModifiers())) { size = adjustForField(size, f); } } } return alignObjectSize(size); } /** Return the set of unsupported JVM features that improve the estimation. */ public static EnumSet getUnsupportedFeatures() { EnumSet unsupported = EnumSet.allOf(JvmFeature.class); unsupported.removeAll(supportedFeatures); return unsupported; } /** Return the set of supported JVM features that improve the estimation. */ public static EnumSet getSupportedFeatures() { return EnumSet.copyOf(supportedFeatures); } /** * Return shallow size of any array. */ private static long shallowSizeOfArray(Object array) { long size = NUM_BYTES_ARRAY_HEADER; final int len = Array.getLength(array); if (len > 0) { Class arrayElementClazz = array.getClass().getComponentType(); if (arrayElementClazz.isPrimitive()) { size += (long) len * primitiveSizes.get(arrayElementClazz); } else { size += (long) NUM_BYTES_OBJECT_REF * len; } } return alignObjectSize(size); } /** * Non-recursive version of object descend. This consumes more memory than recursive in-depth * traversal but prevents stack overflows on long chains of objects * or complex graphs (a max. recursion depth on my machine was ~5000 objects linked in a chain * so not too much). * * @param stack Root objects. */ private static long measureSizeOf(ArrayList stack) { final IdentityHashSet seen = new IdentityHashSet(); final IdentityHashMap, ClassCache> classCache = new IdentityHashMap, ClassCache>(); long totalSize = 0; while (!stack.isEmpty()) { final Object ob = stack.remove(stack.size() - 1); if (ob == null || seen.contains(ob)) { continue; } seen.add(ob); final Class obClazz = ob.getClass(); if (obClazz.isArray()) { /* * Consider an array, possibly of primitive types. Push any of its references to * the processing stack and accumulate this array's shallow size. */ long size = NUM_BYTES_ARRAY_HEADER; final int len = Array.getLength(ob); if (len > 0) { Class componentClazz = obClazz.getComponentType(); if (componentClazz.isPrimitive()) { size += (long) len * primitiveSizes.get(componentClazz); } else { size += (long) NUM_BYTES_OBJECT_REF * len; for (int i = len; --i >= 0 ;) { final Object o = Array.get(ob, i); if (o != null && !seen.contains(o)) { stack.add(o); } } } } totalSize += alignObjectSize(size); } else { /* * Consider an object. Push any references it has to the processing stack * and accumulate this object's shallow size. */ try { ClassCache cachedInfo = classCache.get(obClazz); if (cachedInfo == null) { classCache.put(obClazz, cachedInfo = createCacheEntry(obClazz)); } for (Field f : cachedInfo.referenceFields) { // Fast path to eliminate redundancies. final Object o = f.get(ob); if (o != null && !seen.contains(o)) { stack.add(o); } } totalSize += cachedInfo.alignedShallowInstanceSize; } catch (IllegalAccessException e) { // this should never happen as we enabled setAccessible(). throw new RuntimeException("Reflective field access failed?", e); } } } // Help the GC. seen.clear(); stack.clear(); classCache.clear(); return totalSize; } /** * Create a cached information about shallow size and reference fields for * a given class. */ private static ClassCache createCacheEntry(final Class clazz) { ClassCache cachedInfo; long shallowInstanceSize = NUM_BYTES_OBJECT_HEADER; final ArrayList referenceFields = new ArrayList(32); for (Class c = clazz; c != null; c = c.getSuperclass()) { final Field[] fields = c.getDeclaredFields(); for (final Field f : fields) { if (!Modifier.isStatic(f.getModifiers())) { shallowInstanceSize = adjustForField(shallowInstanceSize, f); if (!f.getType().isPrimitive()) { f.setAccessible(true); referenceFields.add(f); } } } } cachedInfo = new ClassCache( alignObjectSize(shallowInstanceSize), referenceFields.toArray(new Field[referenceFields.size()])); return cachedInfo; } /** * This method returns the maximum representation size of an object. sizeSoFar * is the object's size measured so far. f is the field being probed. * *

      The returned offset will be the maximum of whatever was measured so far and * f field's offset and representation size (unaligned). */ private static long adjustForField(long sizeSoFar, final Field f) { final Class type = f.getType(); final int fsize = type.isPrimitive() ? primitiveSizes.get(type) : NUM_BYTES_OBJECT_REF; if (objectFieldOffsetMethod != null) { try { final long offsetPlusSize = ((Number) objectFieldOffsetMethod.invoke(theUnsafe, f)).longValue() + fsize; return Math.max(sizeSoFar, offsetPlusSize); } catch (IllegalAccessException ex) { throw new RuntimeException("Access problem with sun.misc.Unsafe", ex); } catch (InvocationTargetException ite) { final Throwable cause = ite.getCause(); if (cause instanceof RuntimeException) throw (RuntimeException) cause; if (cause instanceof Error) throw (Error) cause; // this should never happen (Unsafe does not declare // checked Exceptions for this method), but who knows? throw new RuntimeException("Call to Unsafe's objectFieldOffset() throwed "+ "checked Exception when accessing field " + f.getDeclaringClass().getName() + "#" + f.getName(), cause); } } else { // TODO: No alignments based on field type/ subclass fields alignments? return sizeSoFar + fsize; } } /** * Returns size in human-readable units (GB, MB, KB or bytes). */ public static String humanReadableUnits(long bytes) { return humanReadableUnits(bytes, new DecimalFormat("0.#", DecimalFormatSymbols.getInstance(Locale.ENGLISH))); } /** * Returns size in human-readable units (GB, MB, KB or bytes). */ public static String humanReadableUnits(long bytes, DecimalFormat df) { if (bytes / ONE_GB > 0) { return df.format((float) bytes / ONE_GB) + " GB"; } else if (bytes / ONE_MB > 0) { return df.format((float) bytes / ONE_MB) + " MB"; } else if (bytes / ONE_KB > 0) { return df.format((float) bytes / ONE_KB) + " KB"; } else { return bytes + " bytes"; } } /** * Return a human-readable size of a given object. * @see #sizeOf(Object) * @see #humanReadableUnits(long) */ public static String humanSizeOf(Object object) { return humanReadableUnits(sizeOf(object)); } } /** * An identity hash set implemented using open addressing. No null keys are allowed. */ final class IdentityHashSet implements Iterable { /** * Default load factor. */ public final static float DEFAULT_LOAD_FACTOR = 0.75f; /** * Minimum capacity for the set. */ public final static int MIN_CAPACITY = 4; /** * All of set entries. Always of power of two length. */ public Object[] keys; /** * Cached number of assigned slots. */ public int assigned; /** * The load factor for this set (fraction of allocated or deleted slots before * the buffers must be rehashed or reallocated). */ public final float loadFactor; /** * Cached capacity threshold at which we must resize the buffers. */ private int resizeThreshold; /** * Creates a hash set with the default capacity of 16. * load factor of {@value #DEFAULT_LOAD_FACTOR}. ` */ public IdentityHashSet() { this(16, DEFAULT_LOAD_FACTOR); } /** * Creates a hash set with the given capacity, load factor of * {@value #DEFAULT_LOAD_FACTOR}. */ public IdentityHashSet(int initialCapacity) { this(initialCapacity, DEFAULT_LOAD_FACTOR); } /** * Creates a hash set with the given capacity and load factor. */ public IdentityHashSet(int initialCapacity, float loadFactor) { initialCapacity = Math.max(MIN_CAPACITY, initialCapacity); assert initialCapacity > 0 : "Initial capacity must be between (0, " + Integer.MAX_VALUE + "]."; assert loadFactor > 0 && loadFactor < 1 : "Load factor must be between (0, 1)."; this.loadFactor = loadFactor; allocateBuffers(roundCapacity(initialCapacity)); } /** * Adds a reference to the set. Null keys are not allowed. */ public boolean add(KType e) { assert e != null : "Null keys not allowed."; if (assigned >= resizeThreshold) expandAndRehash(); final int mask = keys.length - 1; int slot = rehash(e) & mask; Object existing; while ((existing = keys[slot]) != null) { if (e == existing) { return false; // already found. } slot = (slot + 1) & mask; } assigned++; keys[slot] = e; return true; } /** * Checks if the set contains a given ref. */ public boolean contains(KType e) { final int mask = keys.length - 1; int slot = rehash(e) & mask; Object existing; while ((existing = keys[slot]) != null) { if (e == existing) { return true; } slot = (slot + 1) & mask; } return false; } /** Rehash via MurmurHash. */ private static int rehash(Object o) { return MurmurHash3.hash(System.identityHashCode(o)); } /** * Expand the internal storage buffers (capacity) or rehash current keys and * values if there are a lot of deleted slots. */ private void expandAndRehash() { final Object[] oldKeys = this.keys; assert assigned >= resizeThreshold; allocateBuffers(nextCapacity(keys.length)); /* * Rehash all assigned slots from the old hash table. */ final int mask = keys.length - 1; for (int i = 0; i < oldKeys.length; i++) { final Object key = oldKeys[i]; if (key != null) { int slot = rehash(key) & mask; while (keys[slot] != null) { slot = (slot + 1) & mask; } keys[slot] = key; } } Arrays.fill(oldKeys, null); } /** * Allocate internal buffers for a given capacity. * * @param capacity * New capacity (must be a power of two). */ private void allocateBuffers(int capacity) { this.keys = new Object[capacity]; this.resizeThreshold = (int) (capacity * DEFAULT_LOAD_FACTOR); } /** * Return the next possible capacity, counting from the current buffers' size. */ protected int nextCapacity(int current) { assert current > 0 && Long.bitCount(current) == 1 : "Capacity must be a power of two."; assert ((current << 1) > 0) : "Maximum capacity exceeded (" + (0x80000000 >>> 1) + ")."; if (current < MIN_CAPACITY / 2) current = MIN_CAPACITY / 2; return current << 1; } /** * Round the capacity to the next allowed value. */ protected int roundCapacity(int requestedCapacity) { // Maximum positive integer that is a power of two. if (requestedCapacity > (0x80000000 >>> 1)) return (0x80000000 >>> 1); int capacity = MIN_CAPACITY; while (capacity < requestedCapacity) { capacity <<= 1; } return capacity; } public void clear() { assigned = 0; Arrays.fill(keys, null); } public int size() { return assigned; } public boolean isEmpty() { return size() == 0; } @Override public Iterator iterator() { return new Iterator() { int pos = -1; Object nextElement = fetchNext(); @Override public boolean hasNext() { return nextElement != null; } @SuppressWarnings("unchecked") @Override public KType next() { Object r = this.nextElement; if (r == null) { throw new NoSuchElementException(); } this.nextElement = fetchNext(); return (KType) r; } private Object fetchNext() { pos++; while (pos < keys.length && keys[pos] == null) { pos++; } return (pos >= keys.length ? null : keys[pos]); } @Override public void remove() { throw new UnsupportedOperationException(); } }; } } /** * Hash routines for primitive types. The implementation is based on the * finalization step from Austin Appleby's MurmurHash3. * * @see "http://sites.google.com/site/murmurhash/" */ final class MurmurHash3 { private MurmurHash3() { // no instances. } /** * Hashes a 4-byte sequence (Java int). */ public static int hash(int k) { k ^= k >>> 16; k *= 0x85ebca6b; k ^= k >>> 13; k *= 0xc2b2ae35; k ^= k >>> 16; return k; } /** * Hashes an 8-byte sequence (Java long). */ public static long hash(long k) { k ^= k >>> 33; k *= 0xff51afd7ed558ccdL; k ^= k >>> 33; k *= 0xc4ceb9fe1a85ec53L; k ^= k >>> 33; return k; } } /** * Some useful constants. **/ final class Constants { private Constants() {} // can't construct /** True iff running on a 64bit JVM */ public static final boolean JRE_IS_64BIT; /** The value of System.getProperty("java.version"). **/ public static final String JAVA_VERSION = System.getProperty("java.version"); public static final String JAVA_VENDOR = System.getProperty("java.vendor"); public static final String JVM_VENDOR = System.getProperty("java.vm.vendor"); public static final String JVM_VERSION = System.getProperty("java.vm.version"); public static final String JVM_NAME = System.getProperty("java.vm.name"); public static final String OS_ARCH = System.getProperty("os.arch"); public static final String OS_VERSION = System.getProperty("os.version"); static { final String OS_ARCH = System.getProperty("os.arch"); boolean is64Bit = false; try { final Class unsafeClass = Class.forName("sun.misc.Unsafe"); final Field unsafeField = unsafeClass.getDeclaredField("theUnsafe"); unsafeField.setAccessible(true); final Object unsafe = unsafeField.get(null); final int addressSize = ((Number) unsafeClass.getMethod("addressSize").invoke(unsafe)).intValue(); is64Bit = addressSize >= 8; } catch (Exception e) { final String x = System.getProperty("sun.arch.data.model"); if (x != null) { is64Bit = x.indexOf("64") != -1; } else { if (OS_ARCH != null && OS_ARCH.indexOf("64") != -1) { is64Bit = true; } else { is64Bit = false; } } } JRE_IS_64BIT = is64Bit; } } RequireAssertionsRule.java000066400000000000000000000024711235451432000422170ustar00rootroot00000000000000randomizedtesting-release-2.1.6/randomized-runner/src/main/java/com/carrotsearch/randomizedtesting/rulespackage com.carrotsearch.randomizedtesting.rules; /* * Licensed to the Apache Software Foundation (ASF) under one or more * contributor license agreements. See the NOTICE file distributed with * this work for additional information regarding copyright ownership. * The ASF licenses this file to You under the Apache License, Version 2.0 * (the "License"); you may not use this file except in compliance with * the License. You may obtain a copy of the License at * * http://www.apache.org/licenses/LICENSE-2.0 * * Unless required by applicable law or agreed to in writing, software * distributed under the License is distributed on an "AS IS" BASIS, * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. * See the License for the specific language governing permissions and * limitations under the License. */ import org.junit.ClassRule; import org.junit.rules.TestRule; /** * Require assertions {@link TestRule}. * * @see ClassRule */ public class RequireAssertionsRule extends TestRuleAdapter { @Override protected void before() throws Throwable { try { assert false; throw new Exception("Test class requires assertions, enable assertions globally (-ea) or for Solr/Lucene subpackages only."); } catch (AssertionError e) { // Ok, enabled. } } } StatementAdapter.java000066400000000000000000000037071235451432000411500ustar00rootroot00000000000000randomizedtesting-release-2.1.6/randomized-runner/src/main/java/com/carrotsearch/randomizedtesting/rulespackage com.carrotsearch.randomizedtesting.rules; import java.util.ArrayList; import java.util.List; import org.junit.After; import org.junit.AfterClass; import org.junit.rules.RuleChain; import org.junit.runners.model.MultipleFailureException; import org.junit.runners.model.Statement; /** * An abstract {@link Statement} that guarantees the execution of * {@link #afterAlways} even if an exception has been thrown from delegate * {@link Statement}. This is much like {@link AfterClass} or {@link After} * annotations but can be used with {@link RuleChain} to guarantee the order of * execution. */ public abstract class StatementAdapter extends Statement { private final Statement delegate; protected StatementAdapter(Statement delegate) { this.delegate = delegate; } /** * */ @Override final public void evaluate() throws Throwable { final ArrayList errors = new ArrayList(); try { before(); delegate.evaluate(); afterIfSuccessful(); } catch (Throwable t) { errors.add(t); } try { afterAlways(errors); } catch (Throwable t) { errors.add(t); } MultipleFailureException.assertEmpty(errors); } /** * Always called before the delegate {@link Statement}. */ protected void before() throws Throwable {} /** * Always called after the delegate {@link Statement}, even if an exception * (or assumption failure) occurs. Any exceptions thrown from the body of this * method will be chained using {@link MultipleFailureException}. * * @param errors * A list of errors received so far. The list is modifiable although * should only be extended with new potential exceptions. */ protected void afterAlways(List errors) throws Throwable {} /** * Called only if the delegate {@link Statement} returned successfully. */ protected void afterIfSuccessful() throws Throwable {} } StaticFieldsInvariantRule.java000066400000000000000000000112411235451432000427550ustar00rootroot00000000000000randomizedtesting-release-2.1.6/randomized-runner/src/main/java/com/carrotsearch/randomizedtesting/rulespackage com.carrotsearch.randomizedtesting.rules; import java.lang.reflect.Field; import java.lang.reflect.Modifier; import java.util.ArrayList; import java.util.Collections; import java.util.List; import java.util.Locale; import junit.framework.AssertionFailedError; import org.junit.ClassRule; import org.junit.rules.TestRule; import org.junit.runner.Description; import org.junit.runners.model.Statement; import com.carrotsearch.randomizedtesting.RandomizedContext; /** * A {@link TestRule} that ensures static, reference fields of the suite class * (and optionally its superclasses) are cleaned up after a suite is completed. * This is helpful in finding out static memory leaks (a class references * something huge but is no longer used). * * @see ClassRule * @see #accept(Field) */ public class StaticFieldsInvariantRule implements TestRule { public static final long DEFAULT_LEAK_THRESHOLD = 10 * 1024 * 1024; private final long leakThreshold; private final boolean countSuperclasses; /** * By default use {@link #DEFAULT_LEAK_THRESHOLD} as the threshold and count * in superclasses. */ public StaticFieldsInvariantRule() { this(DEFAULT_LEAK_THRESHOLD, true); } public StaticFieldsInvariantRule(long leakThresholdBytes, boolean countSuperclasses) { this.leakThreshold = leakThresholdBytes; this.countSuperclasses = countSuperclasses; } static class Entry implements Comparable { final Field field; final Object value; long ramUsed; public Entry(Field field, Object value) { this.field = field; this.value = value; } @Override public int compareTo(Entry o) { if (this.ramUsed > o.ramUsed) return -1; if (this.ramUsed < o.ramUsed) return 1; return this.field.toString().compareTo(o.field.toString()); } } @Override public Statement apply(final Statement s, final Description d) { return new StatementAdapter(s) { @Override protected void afterAlways(List errors) throws Throwable { // Try to get the target class from the context, if available. Class testClass = null; try { testClass = RandomizedContext.current().getTargetClass(); } catch (Throwable t) { // Ignore. } if (testClass == null) { // This is JUnit's ugly way that attempts Class.forName and may use a different // classloader... let's use it as a last resort option. testClass = d.getTestClass(); } // No test class? Weird. if (testClass == null) { throw new RuntimeException("Test class could not be acquired from the randomized " + "context or the Description object."); } // Collect all fields first to count references to the same object once. ArrayList fieldsAndValues = new ArrayList(); ArrayList values = new ArrayList(); for (Class c = testClass; countSuperclasses && c.getSuperclass() != null; c = c.getSuperclass()) { for (Field field : c.getDeclaredFields()) { if (Modifier.isStatic(field.getModifiers()) && !field.getType().isPrimitive() && accept(field)) { field.setAccessible(true); Object v = field.get(null); if (v != null) { fieldsAndValues.add(new Entry(field, v)); values.add(v); } } } } final long ramUsage = RamUsageEstimator.sizeOfAll(values); if (ramUsage > leakThreshold) { // Count per-field information to get the heaviest fields. for (Entry e : fieldsAndValues) { e.ramUsed = RamUsageEstimator.sizeOf(e.value); } Collections.sort(fieldsAndValues); StringBuilder b = new StringBuilder(); b.append(String.format(Locale.ENGLISH, "Clean up static fields (in @AfterClass?), " + "your test seems to hang on to approximately %,d bytes (threshold is %,d). " + "Field reference sizes (counted individually):", ramUsage, leakThreshold)); for (Entry e : fieldsAndValues) { b.append(String.format(Locale.ENGLISH, "\n - %,d bytes, %s", e.ramUsed, e.field.toString())); } errors.add(new AssertionFailedError(b.toString())); } } }; } /** * @return Return false to exclude a given field from being * counted. By default final fields are rejected. */ protected boolean accept(Field field) { return !Modifier.isFinal(field.getModifiers()); } }SystemPropertiesInvariantRule.java000066400000000000000000000103431235451432000437420ustar00rootroot00000000000000randomizedtesting-release-2.1.6/randomized-runner/src/main/java/com/carrotsearch/randomizedtesting/rulespackage com.carrotsearch.randomizedtesting.rules; import java.util.*; import org.junit.ClassRule; import org.junit.Rule; import org.junit.rules.TestRule; import org.junit.runner.Description; import org.junit.runners.model.MultipleFailureException; import org.junit.runners.model.Statement; /** * A {@link TestRule} that ensures system properties remain unmodified by the nested * {@link Statement}. This can be applied both at suite level and at test level. * * @see SystemPropertiesRestoreRule * @see ClassRule * @see Rule */ public class SystemPropertiesInvariantRule implements TestRule { /** * Ignored property keys. */ private final HashSet ignoredProperties; /** * Cares about all properties. */ public SystemPropertiesInvariantRule() { this(Collections.emptySet()); } /** * Don't care about the given set of properties. */ public SystemPropertiesInvariantRule(String... ignoredProperties) { this.ignoredProperties = new HashSet(Arrays.asList(ignoredProperties)); } /** * Don't care about the given set of properties. */ public SystemPropertiesInvariantRule(Set ignoredProperties) { this.ignoredProperties = new HashSet(ignoredProperties); } @Override public Statement apply(final Statement s, Description d) { return new Statement() { @Override public void evaluate() throws Throwable { TreeMap before = SystemPropertiesRestoreRule.cloneAsMap(System.getProperties()); ArrayList errors = new ArrayList(); try { s.evaluate(); } catch (Throwable t) { errors.add(t); } finally { final TreeMap after = SystemPropertiesRestoreRule.cloneAsMap(System.getProperties()); // Remove ignored if they exist. before.keySet().removeAll(ignoredProperties); after.keySet().removeAll(ignoredProperties); if (!after.equals(before)) { errors.add( new AssertionError("System properties invariant violated.\n" + collectErrorMessage(before, after))); } // Restore original properties. SystemPropertiesRestoreRule.restore(before, after, ignoredProperties); } MultipleFailureException.assertEmpty(errors); } private StringBuilder collectErrorMessage( TreeMap before, TreeMap after) { TreeSet newKeys = new TreeSet(after.keySet()); newKeys.removeAll(before.keySet()); TreeSet missingKeys = new TreeSet(before.keySet()); missingKeys.removeAll(after.keySet()); TreeSet differentKeyValues = new TreeSet(before.keySet()); differentKeyValues.retainAll(after.keySet()); for (Iterator i = differentKeyValues.iterator(); i.hasNext();) { String key = i.next(); String valueBefore = before.get(key); String valueAfter = after.get(key); if ((valueBefore == null && valueAfter == null) || (valueBefore.equals(valueAfter))) { i.remove(); } } final StringBuilder b = new StringBuilder(); if (!missingKeys.isEmpty()) { b.append("Missing keys:\n"); for (String key : missingKeys) { b.append(" ").append(key) .append("=") .append(before.get(key)) .append("\n"); } } if (!newKeys.isEmpty()) { b.append("New keys:\n"); for (String key : newKeys) { b.append(" ").append(key) .append("=") .append(after.get(key)) .append("\n"); } } if (!differentKeyValues.isEmpty()) { b.append("Different values:\n"); for (String key : differentKeyValues) { b.append(" [old]").append(key) .append("=") .append(before.get(key)).append("\n"); b.append(" [new]").append(key) .append("=") .append(after.get(key)).append("\n"); } } return b; } }; } }SystemPropertiesRestoreRule.java000066400000000000000000000064271235451432000434420ustar00rootroot00000000000000randomizedtesting-release-2.1.6/randomized-runner/src/main/java/com/carrotsearch/randomizedtesting/rulespackage com.carrotsearch.randomizedtesting.rules; import java.util.*; import org.junit.ClassRule; import org.junit.Rule; import org.junit.rules.TestRule; import org.junit.runner.Description; import org.junit.runners.model.Statement; /** * A {@link TestRule} which restores system properties from before the nested * {@link Statement}. * * @see SystemPropertiesInvariantRule * @see ClassRule * @see Rule */ public class SystemPropertiesRestoreRule implements TestRule { /** * Ignored property keys. */ private final HashSet ignoredProperties; /** * Restores all properties. */ public SystemPropertiesRestoreRule() { this(Collections.emptySet()); } /** * @param ignoredProperties Properties that will be ignored (and will not be restored). */ public SystemPropertiesRestoreRule(Set ignoredProperties) { this.ignoredProperties = new HashSet(ignoredProperties); } /** * @param ignoredProperties Properties that will be ignored (and will not be restored). */ public SystemPropertiesRestoreRule(String... ignoredProperties) { this.ignoredProperties = new HashSet(Arrays.asList(ignoredProperties)); } @Override public Statement apply(final Statement s, Description d) { return new Statement() { @Override public void evaluate() throws Throwable { TreeMap before = cloneAsMap(System.getProperties()); try { s.evaluate(); } finally { TreeMap after = cloneAsMap(System.getProperties()); if (!after.equals(before)) { // Restore original properties. restore(before, after, ignoredProperties); } } } }; } static TreeMap cloneAsMap(Properties properties) { TreeMap result = new TreeMap(); for (Enumeration e = properties.propertyNames(); e.hasMoreElements();) { final Object key = e.nextElement(); // Skip non-string properties or values, they're abuse of Properties object. if (key instanceof String) { String value = properties.getProperty((String) key); if (value == null) { Object ovalue = properties.get(key); if (ovalue != null) { // ovalue has to be a non-string object. Skip the property because // System.clearProperty won't be able to cast back the existing value. continue; } } result.put((String) key, value); } } return result; } static void restore( TreeMap before, TreeMap after, Set ignoredKeys) { // Clear anything that is present after but wasn't before. after.keySet().removeAll(before.keySet()); for (String key : after.keySet()) { if (!ignoredKeys.contains(key)) System.clearProperty(key); } // Restore original property values unless they are ignored (then leave). for (Map.Entry e : before.entrySet()) { String key = e.getValue(); if (!ignoredKeys.contains(key)) { if (key == null) { System.clearProperty(e.getKey()); // Can this happen? } else { System.setProperty(e.getKey(), key); } } } } }TestRuleAdapter.java000066400000000000000000000037171235451432000407540ustar00rootroot00000000000000randomizedtesting-release-2.1.6/randomized-runner/src/main/java/com/carrotsearch/randomizedtesting/rulespackage com.carrotsearch.randomizedtesting.rules; import java.util.List; import org.junit.After; import org.junit.AfterClass; import org.junit.rules.RuleChain; import org.junit.rules.TestRule; import org.junit.runner.Description; import org.junit.runners.model.MultipleFailureException; import org.junit.runners.model.Statement; /** * An abstract {@link TestRule} that guarantees the execution of * {@link #afterAlways} even if an exception has been thrown from delegate * {@link Statement}. This is much like {@link AfterClass} or {@link After} * annotations but can be used with {@link RuleChain} to guarantee the order of * execution. */ public abstract class TestRuleAdapter implements TestRule { @Override public Statement apply(final Statement s, final Description d) { return new StatementAdapter(s) { @Override protected void before() throws Throwable { TestRuleAdapter.this.before(); } @Override protected void afterAlways(List errors) throws Throwable { TestRuleAdapter.this.afterAlways(errors); } @Override protected void afterIfSuccessful() throws Throwable { TestRuleAdapter.this.afterIfSuccessful(); } }; } /** * Always called before the delegate {@link Statement}. */ protected void before() throws Throwable {} /** * Always called after the delegate {@link Statement}, even if an exception * (or assumption failure) occurs. Any exceptions thrown from the body of this * method will be chained using {@link MultipleFailureException}. * * @param errors * A list of errors received so far. The list is modifiable although * should only be extended with new potential exceptions. */ protected void afterAlways(List errors) throws Throwable {} /** * Called only if the delegate {@link Statement} returned successfully. */ protected void afterIfSuccessful() throws Throwable {} } randomizedtesting-release-2.1.6/randomized-runner/src/test/000077500000000000000000000000001235451432000241005ustar00rootroot00000000000000randomizedtesting-release-2.1.6/randomized-runner/src/test/java/000077500000000000000000000000001235451432000250215ustar00rootroot00000000000000randomizedtesting-release-2.1.6/randomized-runner/src/test/java/com/000077500000000000000000000000001235451432000255775ustar00rootroot00000000000000randomizedtesting-release-2.1.6/randomized-runner/src/test/java/com/carrotsearch/000077500000000000000000000000001235451432000302575ustar00rootroot00000000000000randomizedtesting-release-2.1.6/randomized-runner/src/test/java/com/carrotsearch/randomizedtesting/000077500000000000000000000000001235451432000340115ustar00rootroot00000000000000TestChildTestGroupThreads.java000066400000000000000000000011271235451432000416510ustar00rootroot00000000000000randomizedtesting-release-2.1.6/randomized-runner/src/test/java/com/carrotsearch/randomizedtestingpackage com.carrotsearch.randomizedtesting; import java.util.Random; import org.junit.Test; /** * Make sure we can access contexts from a sub-thread group. */ public class TestChildTestGroupThreads extends RandomizedTest { volatile int guard; @Test public void testSubgroup() throws Exception { ThreadGroup tgroup = new ThreadGroup("child group"); final Thread t = new Thread(tgroup, "child thread") { public void run() { Random rnd = RandomizedContext.current().getRandom(); guard += rnd.nextInt(); } }; t.start(); t.join(); } } TestClassMethodFiltering.java000066400000000000000000000061571235451432000415200ustar00rootroot00000000000000randomizedtesting-release-2.1.6/randomized-runner/src/test/java/com/carrotsearch/randomizedtestingpackage com.carrotsearch.randomizedtesting; import static org.junit.Assert.*; import java.util.ArrayList; import java.util.Arrays; import java.util.List; import org.junit.After; import org.junit.Before; import org.junit.BeforeClass; import org.junit.Test; import org.junit.runner.JUnitCore; import org.junit.runner.RunWith; import static com.carrotsearch.randomizedtesting.SysGlobals.*; /** * Check if global filtering works. */ public class TestClassMethodFiltering extends WithNestedTestClass { static List methods = new ArrayList(); @RunWith(RandomizedRunner.class) public static class Nested1 { @BeforeClass public static void beforeClass() { methods.add("beforeClass1"); } @Test public void method1() { assumeRunningNested(); methods.add("method1"); } @Test public void method2() { assumeRunningNested(); methods.add("method2"); } } @RunWith(RandomizedRunner.class) public static class Nested2 { @BeforeClass public static void beforeClass() { methods.add("beforeClass2"); } @Test public void method1() { assumeRunningNested(); methods.add("method1"); } } /** * Class filter (all methods). */ @Test public void testClassFilter() { System.setProperty(SYSPROP_TESTCLASS(), Nested1.class.getName()); JUnitCore.runClasses(Nested1.class, Nested2.class); assertTrue( Arrays.asList("beforeClass1", "method1", "method2").equals(methods) || Arrays.asList("beforeClass1", "method2", "method1").equals(methods)); } /** * Class and method filter (single method). */ @Test public void testClassMethodFilter() { System.setProperty(SYSPROP_TESTCLASS(), Nested1.class.getName()); System.setProperty(SYSPROP_TESTMETHOD(), "method2"); JUnitCore.runClasses(Nested1.class, Nested2.class); assertEquals(Arrays.asList("beforeClass1", "method2"), methods); } /** * Awkward case: only method filter. */ @Test public void testMethodFilter() { System.setProperty(SYSPROP_TESTMETHOD(), "method1"); JUnitCore.runClasses(Nested1.class, Nested2.class); assertEquals(Arrays.asList("beforeClass1", "method1", "beforeClass2", "method1"), methods); } /** * Glob class name filter· */ @Test public void testGlobClassName() { System.setProperty(SYSPROP_TESTCLASS(), "*Nested1"); JUnitCore.runClasses(Nested1.class, Nested2.class); assertTrue( Arrays.asList("beforeClass1", "method1", "method2").equals(methods) || Arrays.asList("beforeClass1", "method2", "method1").equals(methods)); } /** * Glob method name filter· */ @Test public void testGlobMethodName() { System.setProperty(SYSPROP_TESTMETHOD(), "*hod1"); JUnitCore.runClasses(Nested1.class, Nested2.class); assertEquals(Arrays.asList("beforeClass1", "method1", "beforeClass2", "method1"), methods); } @Before public void cleanupBefore() { cleanupAfter(); } @After public void cleanupAfter() { System.clearProperty(SYSPROP_TESTCLASS()); System.clearProperty(SYSPROP_TESTMETHOD()); methods.clear(); } } TestContextRandom.java000066400000000000000000000046071235451432000402310ustar00rootroot00000000000000randomizedtesting-release-2.1.6/randomized-runner/src/test/java/com/carrotsearch/randomizedtestingpackage com.carrotsearch.randomizedtesting; import java.util.ArrayList; import java.util.List; import org.junit.Assert; import org.junit.Ignore; import org.junit.Test; import org.junit.runner.JUnitCore; import com.carrotsearch.randomizedtesting.annotations.Seed; /** * Check if the context's random is indeed repeatable. */ public class TestContextRandom extends WithNestedTestClass { static ArrayList numbers = new ArrayList(); public static class Nested1 extends RandomizedTest { @Seed("deadbeef") // Fix the seed to get a repeatable result @Test public void testMethod() { numbers.clear(); for (int i = 0; i < 10; i++) { numbers.add(randomInt()); } } } public static class Nested2 extends RandomizedTest { @Test public void testMethod() { numbers.clear(); for (int i = 0; i < 10; i++) { numbers.add(randomInt()); } } } public static class Nested3 extends RandomizedTest { @Seed("deadbeef") // Fix the seed to get a repeatable result even if subthreads use randomness. @Test public void testMethod() throws Exception { Thread t = new Thread() { @Override public void run() { numbers.clear(); for (int i = 0; i < 10; i++) { numbers.add(randomInt()); } } }; t.start(); t.join(); } } /** * Check that subthreads get the same randomness for {@link Seed} * annotation on a method. */ @Test @Ignore("Forked threads get the master seed (by-design).") public void testFixedSeedSubthreads() { JUnitCore.runClasses(Nested3.class); List run1 = new ArrayList(numbers); JUnitCore.runClasses(Nested3.class); List run2 = new ArrayList(numbers); Assert.assertEquals(run1, run2); } @Test public void testFixedSeed() { JUnitCore.runClasses(Nested1.class); List run1 = new ArrayList(numbers); JUnitCore.runClasses(Nested1.class); List run2 = new ArrayList(numbers); Assert.assertEquals(run1, run2); } @Test public void testRandomSeed() { JUnitCore.runClasses(Nested2.class); List run1 = new ArrayList(numbers); JUnitCore.runClasses(Nested2.class); List run2 = new ArrayList(numbers); Assert.assertFalse(run1.equals(run2)); } } TestCustomMethodProvider.java000066400000000000000000000046761235451432000416000ustar00rootroot00000000000000randomizedtesting-release-2.1.6/randomized-runner/src/test/java/com/carrotsearch/randomizedtestingpackage com.carrotsearch.randomizedtesting; import java.lang.annotation.ElementType; import java.lang.annotation.Inherited; import java.lang.annotation.Retention; import java.lang.annotation.RetentionPolicy; import java.lang.annotation.Target; import org.junit.Assert; import org.junit.Test; import org.junit.runner.JUnitCore; import org.junit.runner.Result; import org.junit.runners.model.InitializationError; import com.carrotsearch.randomizedtesting.annotations.TestMethodProviders; public class TestCustomMethodProvider extends WithNestedTestClass { @Retention(RetentionPolicy.RUNTIME) @Target({ElementType.METHOD}) @Inherited public static @interface MyTest { } public static class MyTestMethodProvider extends AnnotatedMethodProvider { public MyTestMethodProvider() { super(MyTest.class); } } @TestMethodProviders({MyTestMethodProvider.class}) public static class Base {} public static class T4 extends Base { @MyTest private void test1() {} } public static class T2 extends Base { @MyTest void test1() {} } public static class T3 extends Base { @MyTest protected void test1() {} } public static class T1 extends Base { @MyTest public void test1() {} } public static class ST4 extends Base { @MyTest static private void test1() {} } public static class ST2 extends Base { @MyTest static void test1() {} } public static class ST3 extends Base { @MyTest static protected void test1() {} } public static class ST1 extends Base { @MyTest static public void test1() {} } public static class AT1 extends Base { @MyTest public void test1(int arg) {} } public static class RT1 extends Base { @MyTest public int test1() { return 0; } } @Test public void testJUnit4Valid() throws InitializationError { Class [] valid = { T1.class, RT1.class }; for (Class cl : valid) { Result r = new JUnitCore().run(new RandomizedRunner(cl)); Assert.assertEquals(0, r.getFailureCount()); Assert.assertEquals(1, r.getRunCount()); } } @Test public void testJUnit4Invalid() { Class [] invalid = { T2.class, T3.class, T4.class, ST1.class, ST2.class, ST3.class, ST4.class, AT1.class }; for (Class cl : invalid) { try { new JUnitCore().run(new RandomizedRunner(cl)); Assert.fail("Expected to fail for: " + cl); } catch (InitializationError e) { // expected. } } } } TestExpected.java000066400000000000000000000026721235451432000372050ustar00rootroot00000000000000randomizedtesting-release-2.1.6/randomized-runner/src/test/java/com/carrotsearch/randomizedtestingpackage com.carrotsearch.randomizedtesting; import junit.framework.Assert; import org.junit.Test; import org.junit.runner.JUnitCore; import org.junit.runner.Result; /** * Test {@link Test#expected()}. */ public class TestExpected extends WithNestedTestClass { public static class Nested extends RandomizedTest { @Test(expected = RuntimeException.class) public void testMethod1() { throw new RuntimeException(); } // We expect a RuntimeException but get an error: should fail. @Test(expected = RuntimeException.class) public void testMethod2() { assumeRunningNested(); throw new Error(); } } public static class Nested2 extends RandomizedTest { @Test(expected = RuntimeException.class) public void testMethod1() { assumeRunningNested(); // Don't do anything. } } @Test public void testSameMethodRandomnessWithFixedRunner() { Result result = JUnitCore.runClasses(Nested.class); Assert.assertEquals(0, result.getIgnoreCount()); Assert.assertEquals(2, result.getRunCount()); Assert.assertEquals(1, result.getFailureCount()); Assert.assertSame(Error.class, result.getFailures().get(0).getException() .getClass()); } @Test public void testSuccessfulExceptedFailure() { Result result = JUnitCore.runClasses(Nested2.class); Assert.assertEquals(1, result.getRunCount()); Assert.assertEquals(1, result.getFailureCount()); } } TestFailurePropagationCompatibility.java000066400000000000000000000107341235451432000437670ustar00rootroot00000000000000randomizedtesting-release-2.1.6/randomized-runner/src/test/java/com/carrotsearch/randomizedtestingpackage com.carrotsearch.randomizedtesting; import java.util.ArrayList; import java.util.Random; import org.junit.*; import org.junit.rules.RuleChain; import org.junit.rules.TestRule; import org.junit.runner.*; import org.junit.runner.notification.Failure; import org.junit.runners.model.MultipleFailureException; import org.junit.runners.model.Statement; /** * Check failure propagation compatibility against JUnit. */ public class TestFailurePropagationCompatibility extends WithNestedTestClass { static Random random; static int frequency; public static class MaybeFailRule implements TestRule { @Override public Statement apply(final Statement base, Description description) { return new Statement() { @Override public void evaluate() throws Throwable { try { maybeFail(); base.evaluate(); maybeFail(); } catch (Throwable t) { maybeFail(); } finally { maybeFail(); } } }; } } public static class FailRandomly1 { public FailRandomly1() { maybeFail(); } @ClassRule public static TestRule classRule1 = RuleChain .outerRule(new MaybeFailRule()) .around(new MaybeFailRule()); @Rule public TestRule testRule1 = RuleChain .outerRule(new MaybeFailRule()) .around(new MaybeFailRule()); @BeforeClass public static void beforeClass1() { maybeFail(); } @Before public void before() { maybeFail(); } @Test public void test() { maybeFail(); } @After public void after() { maybeFail(); } @AfterClass public static void afterClass() { maybeFail(); } } public static class FailRandomly2 extends FailRandomly1 { public FailRandomly2() { maybeFail(); } @ClassRule public static TestRule classRule2 = RuleChain .outerRule(new MaybeFailRule()) .around(new MaybeFailRule()); @Rule public TestRule testRule2 = RuleChain .outerRule(new MaybeFailRule()) .around(new MaybeFailRule()); @BeforeClass public static void beforeClass2() { maybeFail(); } @Before public void before2() { maybeFail(); } @After public void after2() { maybeFail(); } @AfterClass public static void afterClass2() { maybeFail(); } } @RunWith(RandomizedRunner.class) public static class FailRandomly3 extends FailRandomly2 { } static void maybeFail() { if (random != null) { if (random.nextInt(frequency) == 0) { if (random.nextBoolean()) { throw new RuntimeException("State: " + random.nextLong()); } else { ArrayList errors = new ArrayList(); errors.add(new RuntimeException("State: " + random.nextLong())); errors.add(new RuntimeException("State: " + random.nextLong())); // Throw MultipleFailureException as if unchecked. Rethrow.rethrow(new MultipleFailureException(errors)); } } } } @Test public void testRunEquals() throws Exception { Random rnd = new Random(); // initial. for (int f = 1; f < 10; f += 2) { frequency = f; for (int i = 0; i < 25; i++) { final long seed = rnd.nextLong() + i; random = new Random(seed); Result junit4 = new JUnitCore().run(FailRandomly2.class); random = new Random(seed); Result rr = new JUnitCore().run(FailRandomly3.class); String traceJunit4 = executionTrace(junit4); String traceRR = executionTrace(rr); if (!traceJunit4.equals(traceRR)) { System.out.println("=== Random(" + seed + "), freq: " + frequency); System.out.println("--- JUnit4:"); System.out.println(traceJunit4); System.out.println("--- RandomizedRunner:"); System.out.println(traceRR); Assert.fail(); } } } } @AfterClass public static void cleanup() { random = null; } private String executionTrace(Result r) { StringBuilder sb = new StringBuilder(); sb.append("Run count: " + r.getRunCount() + "\n"); sb.append("Ignore count: " + r.getIgnoreCount() + "\n"); sb.append("Failure count: " + r.getFailureCount() + "\n"); for (Failure f : r.getFailures()) { Throwable t = f.getException(); sb.append(t.getClass().getName() + ": " + t.getMessage()); sb.append("\n\n"); } return sb.toString(); } } TestFilterExpressionParser.java000066400000000000000000000110361235451432000421200ustar00rootroot00000000000000randomizedtesting-release-2.1.6/randomized-runner/src/test/java/com/carrotsearch/randomizedtestingpackage com.carrotsearch.randomizedtesting; import java.util.ArrayDeque; import java.util.Arrays; import java.util.Deque; import java.util.List; import org.fest.assertions.api.Assertions; import org.junit.Test; import com.carrotsearch.randomizedtesting.FilterExpressionParser.IContext; import com.carrotsearch.randomizedtesting.FilterExpressionParser.Node; import com.carrotsearch.randomizedtesting.FilterExpressionParser.SyntaxException; public class TestFilterExpressionParser { @Test public void testParsingSanity() { // input -> expected bracketing. Deque examples = new ArrayDeque(Arrays.asList( "", "default", "default", "default", "@nightly", "@nightly", "@nightly or @slow", "(@nightly OR @slow)", "@nightly and @slow", "(@nightly AND @slow)", "@nightly and not @slow", "(@nightly AND (NOT @slow))", "@nightly and (not @slow)", "(@nightly AND (NOT @slow))", "not @slow", "(NOT @slow)", "not not @slow", "(NOT (NOT @slow))", "not @nightly or @slow", "((NOT @nightly) OR @slow)", "not(@nightly or @slow)", "(NOT (@nightly OR @slow))", "(@nightly and (not @slow))", "(@nightly AND (NOT @slow))")); while (!examples.isEmpty()) { String input = examples.remove(); String expected = examples.remove(); System.out.println("-- " + input); Node root = new FilterExpressionParser().parse(input); String expression = root.toExpression(); System.out.println(" " + expression); Assertions.assertThat(expression) .as(input) .isEqualTo(expected); Assertions.assertThat(new FilterExpressionParser().parse(expression).toExpression()) .as(input) .isEqualTo(expression); } } @Test public void testTrueExpressions() { // {groups}, {rules} Deque examples = new ArrayDeque(Arrays.asList(new String [][] { {}, {"not @foo", "not default"}, {"@nightly"}, {"@nightly", "@nightly or @foo", "@foo or @nightly", "not not @nightly"}, {"@nightly", "@slow"}, {"@nightly and @slow", "@nightly and not @foo", "not @nightly or @slow"}, {"default"}, {"", "default"}, })); while (!examples.isEmpty()) { final List groups = Arrays.asList((String[]) examples.pop()); IContext context = new IContext() { @Override public boolean defaultValue() { return hasGroup("default"); } @Override public boolean hasGroup(String value) { return groups.contains(value); } }; for (String rule : examples.pop()) { Assertions.assertThat(new FilterExpressionParser().parse(rule).evaluate(context)) .as("ctx=" + groups + ", rule=" + rule) .isEqualTo(true); } } } @Test public void testFalseExpressions() { // {groups}, {rules} Deque examples = new ArrayDeque(Arrays.asList(new String [][] { {}, {"@foo", "default"}, {"@nightly"}, {"not @nightly", "@nightly and @foo"}, {"@nightly", "@slow"}, {"not(@nightly or @slow)"}, })); while (!examples.isEmpty()) { final List groups = Arrays.asList((String[]) examples.pop()); IContext context = new IContext() { @Override public boolean defaultValue() { return hasGroup("default"); } @Override public boolean hasGroup(String value) { return groups.contains(value); } }; for (String rule : examples.pop()) { Assertions.assertThat(new FilterExpressionParser().parse(rule).evaluate(context)) .as("ctx=" + groups + ", rule=" + rule) .isEqualTo(false); } } } @Test public void testErrors() { for (String rule : Arrays.asList( "nightly", "@nightly and ", "@nightly or ", "@nightly and or @slow", "and not @slow", "(@nightly))", "((@nightly or @slow)" )) { System.out.println("-- " + rule); try { new FilterExpressionParser().parse(rule); Assertions.fail("Should cause an exception: " + rule); } catch (SyntaxException e) { System.out.println(" " + e.getMessage()); } } } @Test public void testInvalidToken() { try { new FilterExpressionParser().parse("@nightly and foo or @bar"); } catch (SyntaxException e) { Assertions.assertThat(e.toString()).contains(">foo<"); } } } TestFilteringWarnings.java000066400000000000000000000076071235451432000411030ustar00rootroot00000000000000randomizedtesting-release-2.1.6/randomized-runner/src/test/java/com/carrotsearch/randomizedtestingpackage com.carrotsearch.randomizedtesting; import java.util.logging.*; import org.junit.*; import org.junit.runner.JUnitCore; import org.junit.runner.Result; import org.junit.runner.manipulation.Filterable; import com.carrotsearch.randomizedtesting.rules.SystemPropertiesRestoreRule; /** * Test warnings resulting from potential misuse of {@link Filterable} interface. */ public class TestFilteringWarnings extends WithNestedTestClass { @Rule public SystemPropertiesRestoreRule restoreProperties = new SystemPropertiesRestoreRule(); private Logger rootLogger; private Handler[] handlers; private StringBuilder buffer = new StringBuilder(); private Handler bufferingHandler = new Handler() { @Override public void publish(LogRecord record) { buffer.append(record.getMessage()); } @Override public void flush() {} @Override public void close() throws SecurityException {} }; /** * Test class. */ public static class Nested extends RandomizedTest { @Test public void method() { // Just in case... Assume.assumeTrue(getContext().getRunnerSeed() != 0x614CDBEAE7160809L); } } @Before public void setup() throws Exception { // Attach to the root logger. LogManager logManager = LogManager.getLogManager(); rootLogger = logManager.getLogger(""); for (Handler h : (handlers = rootLogger.getHandlers())) { rootLogger.removeHandler(h); } rootLogger.addHandler(bufferingHandler); } @After public void cleanup() { buffer.setLength(0); rootLogger.removeHandler(bufferingHandler); for (Handler h : handlers) { rootLogger.addHandler(h); } } /** * Filter contains a seed but random seed will generate unique repetitions. */ @Test public void testItersWithRandomSeed() { System.setProperty(SysGlobals.SYSPROP_ITERATIONS(), "5"); System.setProperty(SysGlobals.SYSPROP_TESTMETHOD(), "method {#1 seed=[614CDBEAE7160809:AE4F94CE0834589A]}"); Result result = JUnitCore.runClasses(Nested.class); if (result.getIgnoreCount() == 0) { Assert.assertTrue(result.getFailures().isEmpty()); Assert.assertTrue(getOutput().contains("Empty set of tests for suite class Nested after filters applied")); } } /** * Filter contains a seed but random seed will generate unique repetitions. */ @Test public void testItersWithFixedSeed() { System.setProperty(SysGlobals.SYSPROP_ITERATIONS(), "5"); System.setProperty(SysGlobals.SYSPROP_TESTMETHOD(), "method {#1 seed=[614CDBEAE7160809:AE4F94CE0834589A]}"); System.setProperty(SysGlobals.SYSPROP_RANDOM_SEED(), "deadbeef"); Result result = JUnitCore.runClasses(Nested.class); if (result.getIgnoreCount() == 0) { Assert.assertTrue(result.getFailures().isEmpty()); Assert.assertTrue(getOutput().contains("Empty set of tests for suite class Nested after filters applied")); } } /** * */ @Test public void testItersWithFixedMethodName() { System.setProperty(SysGlobals.SYSPROP_ITERATIONS(), "5"); System.setProperty(SysGlobals.SYSPROP_TESTMETHOD(), "foo"); Result result = JUnitCore.runClasses(Nested.class); if (result.getIgnoreCount() == 0) { Assert.assertTrue(result.getFailures().isEmpty()); Assert.assertTrue(getOutput().contains("Empty set of tests for suite class Nested after filters applied")); } } /** * Filter contains a seed but random seed will generate unique repetitions. */ @Test public void testNoIters() { System.setProperty(SysGlobals.SYSPROP_TESTMETHOD(), "method"); System.setProperty(SysGlobals.SYSPROP_RANDOM_SEED(), "deadbeef"); Result result = JUnitCore.runClasses(Nested.class); if (result.getIgnoreCount() == 0) { Assert.assertTrue(result.getFailures().isEmpty()); Assert.assertTrue(getOutput().isEmpty()); } } private String getOutput() { return buffer.toString(); } } TestFormattingRandomSeeds.java000066400000000000000000000014341235451432000416760ustar00rootroot00000000000000randomizedtesting-release-2.1.6/randomized-runner/src/test/java/com/carrotsearch/randomizedtestingpackage com.carrotsearch.randomizedtesting; import org.junit.Assert; import org.junit.Test; import org.junit.runner.RunWith; import com.carrotsearch.randomizedtesting.annotations.Repeat; @RunWith(RandomizedRunner.class) public class TestFormattingRandomSeeds { @Test public void minusOne() { check(-1L); } @Test public void zero() { check(0); } @Test public void maxLong() { check(Long.MAX_VALUE); } /** Heck, why not use ourselves here? ;) */ @Test @Repeat(iterations = 1000) public void noise() { check(RandomizedContext.current().getRandom().nextLong()); } private void check(long seed) { String asString = SeedUtils.formatSeedChain(new Randomness(seed)); Assert.assertEquals(seed, SeedUtils.parseSeedChain(asString)[0]); } } TestHookMethodOrderWithExceptions.java000066400000000000000000000074141235451432000433760ustar00rootroot00000000000000randomizedtesting-release-2.1.6/randomized-runner/src/test/java/com/carrotsearch/randomizedtestingpackage com.carrotsearch.randomizedtesting; import java.util.ArrayList; import java.util.List; import java.util.Random; import org.junit.After; import org.junit.AfterClass; import org.junit.Assert; import org.junit.Before; import org.junit.BeforeClass; import org.junit.Test; import org.junit.runner.JUnitCore; import org.junit.runner.Request; import org.junit.runner.Result; import org.junit.runner.Runner; import org.junit.runner.notification.RunListener; import org.junit.runner.notification.RunNotifier; import com.carrotsearch.randomizedtesting.annotations.Repeat; /** * Try to be compatible with JUnit's runners wrt method hooks throwing * exceptions. */ public class TestHookMethodOrderWithExceptions extends RandomizedTest { static final List callOrder = new ArrayList(); /* * We don't want to run nested classes as separate tests, but eclipse still * wants to run them. this is a hack, but I don't know how to do it cleaner. */ static boolean testExecution; /** * Test superclass. */ public static class Super { static Random rnd; @BeforeClass public static void beforeClassSuper() { callOrder.add("beforeClassSuper"); maybeThrowException(); } @Before public final void beforeTest() { callOrder.add("beforeTestSuper"); maybeThrowException(); } @After public final void afterTest() { callOrder.add("afterTestSuper"); maybeThrowException(); } @AfterClass public static void afterClassSuper() { callOrder.add("afterClassSuper"); maybeThrowException(); } public static void maybeThrowException() { if (testExecution && rnd.nextInt(10) == 0) { throw new RuntimeException(); } } } /** * Test subclass. */ public static class SubSub extends Super { @BeforeClass public static void beforeClass() { callOrder.add("beforeClassSub"); maybeThrowException(); } @Before public void beforeTestSub() { callOrder.add("beforeTestSub"); maybeThrowException(); } @Test public void testMethod() { callOrder.add("testMethodSub"); maybeThrowException(); } @After public void afterTestSub() { callOrder.add("afterTestSub"); maybeThrowException(); } @AfterClass public static void afterClass() { callOrder.add("afterClassSub"); maybeThrowException(); } } @Before public void setup() { callOrder.clear(); testExecution = true; } @After public void cleanup() { callOrder.clear(); testExecution = false; } @Test @Repeat(iterations = 20) public void checkOrderSameAsJUnit() throws Exception { long seed = RandomizedContext.current().getRandomness().getSeed(); callOrder.clear(); Super.rnd = new Random(seed); Result junit = JUnitCore.runClasses(SubSub.class); List junitOrder = new ArrayList(callOrder); callOrder.clear(); Super.rnd = new Random(seed); Result rrunner = runRequest(Request.runner(new RandomizedRunner(SubSub.class))); List rrunnerOrder = new ArrayList(callOrder); Assert.assertEquals(junitOrder, rrunnerOrder); Assert.assertEquals(junit.getRunCount(), rrunner.getRunCount()); } private Result runRequest(Request request) { Result result = new Result(); RunNotifier notifier = new RunNotifier(); RunListener listener = result.createListener(); notifier.addFirstListener(listener); try { Runner runner = request.getRunner(); notifier.fireTestRunStarted(runner.getDescription()); runner.run(notifier); notifier.fireTestRunFinished(result); } finally { notifier.removeListener(listener); } return result; } } TestHooksWithEmptyTestSet.java000066400000000000000000000023251235451432000417110ustar00rootroot00000000000000randomizedtesting-release-2.1.6/randomized-runner/src/test/java/com/carrotsearch/randomizedtestingpackage com.carrotsearch.randomizedtesting; import static org.junit.Assert.*; import org.junit.AfterClass; import org.junit.BeforeClass; import org.junit.Test; import org.junit.runner.JUnitCore; import org.junit.runner.Result; import org.junit.runner.RunWith; /** * Hooks should _not_ execute if there are no test cases to run. Note that * ignored test cases behave as if there was something to execute (!). */ public class TestHooksWithEmptyTestSet { @RunWith(RandomizedRunner.class) public static class Nested { static boolean beforeClassExecuted; static boolean afterClassExecuted; @BeforeClass public static void beforeClass() { beforeClassExecuted = true; } @AfterClass public static void afterClass() { afterClassExecuted = true; } } /** * Check if methods get the same seed on every run with a fixed runner's seed. */ @Test public void testSameMethodRandomnessWithFixedRunner() { Nested.beforeClassExecuted = false; Nested.afterClassExecuted = false; Result result = JUnitCore.runClasses(Nested.class); assertEquals(0, result.getRunCount()); assertFalse(Nested.beforeClassExecuted); assertFalse(Nested.afterClassExecuted); } } TestIgnoredRunCount.java000066400000000000000000000015241235451432000405240ustar00rootroot00000000000000randomizedtesting-release-2.1.6/randomized-runner/src/test/java/com/carrotsearch/randomizedtestingpackage com.carrotsearch.randomizedtesting; import org.junit.*; import org.junit.runner.*; /** * Test {@link Result}'s run count for ignored tests. */ public class TestIgnoredRunCount extends WithNestedTestClass { public static class Nested { @Test @Ignore public void ignored() { } } @Test public void checkIgnoredCount() throws Exception { assertSameExecution(Nested.class); } private void assertSameExecution(Class clazz) throws Exception { Result result1 = JUnitCore.runClasses(clazz); Result result2 = new JUnitCore().run(Request.runner(new RandomizedRunner(clazz))); Assert.assertEquals(result1.getRunCount(), result2.getRunCount()); Assert.assertEquals(result1.getFailureCount(), result2.getFailureCount()); Assert.assertEquals(result1.getIgnoreCount(), result2.getIgnoreCount()); } } TestInstantiationTime.java000066400000000000000000000011221235451432000410740ustar00rootroot00000000000000randomizedtesting-release-2.1.6/randomized-runner/src/test/java/com/carrotsearch/randomizedtestingpackage com.carrotsearch.randomizedtesting; import org.junit.BeforeClass; import org.junit.Test; /** * Check that {@link BeforeClass} hooks are called before instance initializers. */ public class TestInstantiationTime extends RandomizedTest { private static String constant; /** * Instance initializer. Will result in an NPE if * {@link #prepare()} is not invoked before. */ public String copyOfStatic = constant.toUpperCase(); @BeforeClass public static void prepare() { constant = "constant"; } @Test public void testDummy() { // empty. } } TestIterationsAnnotation.java000066400000000000000000000011231235451432000416060ustar00rootroot00000000000000randomizedtesting-release-2.1.6/randomized-runner/src/test/java/com/carrotsearch/randomizedtestingpackage com.carrotsearch.randomizedtesting; import org.junit.AfterClass; import org.junit.Assert; import org.junit.BeforeClass; import org.junit.Test; import com.carrotsearch.randomizedtesting.annotations.Repeat; /** * Nightly mode checks. */ public class TestIterationsAnnotation extends RandomizedTest { static int iterations = 0; @Test @Repeat(iterations = 10) public void nightly() { iterations++; } @BeforeClass public static void clean() { iterations = 0; } @AfterClass public static void cleanupAfter() { Assert.assertEquals(10, iterations); } } TestJ9SysThreads.java000066400000000000000000000022341235451432000377320ustar00rootroot00000000000000randomizedtesting-release-2.1.6/randomized-runner/src/test/java/com/carrotsearch/randomizedtestingpackage com.carrotsearch.randomizedtesting; import java.lang.management.ManagementFactory; import java.lang.management.MemoryPoolMXBean; import junit.framework.Assert; import org.junit.Test; import org.junit.runner.JUnitCore; import org.junit.runner.Result; import com.carrotsearch.randomizedtesting.annotations.ThreadLeakAction; import com.carrotsearch.randomizedtesting.annotations.ThreadLeakAction.Action; import com.carrotsearch.randomizedtesting.annotations.ThreadLeakScope; import com.carrotsearch.randomizedtesting.annotations.ThreadLeakScope.Scope; /** * Test {@link Test#expected()}. */ public class TestJ9SysThreads extends WithNestedTestClass { @ThreadLeakScope(Scope.SUITE) @ThreadLeakAction({Action.INTERRUPT}) public static class Nested extends RandomizedTest { @Test public void testMethod1() { for (MemoryPoolMXBean mbean : ManagementFactory.getMemoryPoolMXBeans()) { mbean.getUsage(); sysout.println(mbean.getClass().getName()); } } } @Test public void testSuccessfulExceptedFailure() { Result result = JUnitCore.runClasses(Nested.class); Assert.assertEquals(0, result.getFailureCount()); } } TestJUnit3MethodProvider.java000066400000000000000000000046411235451432000414320ustar00rootroot00000000000000randomizedtesting-release-2.1.6/randomized-runner/src/test/java/com/carrotsearch/randomizedtestingpackage com.carrotsearch.randomizedtesting; import org.junit.Assert; import org.junit.Test; import org.junit.runner.JUnitCore; import org.junit.runner.Result; import org.junit.runners.model.InitializationError; import com.carrotsearch.randomizedtesting.annotations.TestMethodProviders; public class TestJUnit3MethodProvider { @TestMethodProviders({JUnit3MethodProvider.class}) public static class Base {} @SuppressWarnings("unused") public static class T4 extends Base { private void test1() {} } public static class T2 extends Base { void test1() {} } public static class T3 extends Base { protected void test1() {} } public static class T1 extends Base { public void test1() {} } @SuppressWarnings("unused") public static class ST4 extends Base { static private void test1() {} } public static class ST2 extends Base { static void test1() {} } public static class ST3 extends Base { static protected void test1() {} } public static class ST1 extends Base { static public void test1() {} } public static class AT1 extends Base { public void test1(int arg) {} } public static class RT1 extends Base { public int test1() { return 0; } } @Test public void testJUnit3Valid() throws Exception { Class [] valid = { T1.class, RT1.class }; for (Class cl : valid) { Result r = new JUnitCore().run(new RandomizedRunner(cl)); Assert.assertEquals(0, r.getFailureCount()); Assert.assertEquals(1, r.getRunCount()); } } @Test public void testJUnit3Invalid() { Class [] invalid = { T2.class, T3.class, T4.class, ST1.class, ST2.class, ST3.class, ST4.class, AT1.class }; for (Class cl : invalid) { try { new JUnitCore().run(new RandomizedRunner(cl)); Assert.fail("Expected to fail for: " + cl); } catch (InitializationError e) { // expected. } } } public static class S1 extends Base { public void test1() {} } public static class S2 extends S1 { public void test1() {} } public static class S3 extends S2 { public void test1() {} } @Test public void testJUnit3Overrides() throws Exception { Result r = new JUnitCore().run(new RandomizedRunner(S3.class)); Assert.assertEquals(0, r.getFailureCount()); Assert.assertEquals(1, r.getRunCount()); } } TestListenersAnnotation.java000066400000000000000000000050771235451432000414510ustar00rootroot00000000000000randomizedtesting-release-2.1.6/randomized-runner/src/test/java/com/carrotsearch/randomizedtestingpackage com.carrotsearch.randomizedtesting; import java.util.ArrayList; import java.util.List; import org.junit.Assert; import org.junit.Assume; import org.junit.Ignore; import org.junit.Test; import org.junit.runner.Description; import org.junit.runner.JUnitCore; import org.junit.runner.Result; import org.junit.runner.notification.Failure; import org.junit.runner.notification.RunListener; import com.carrotsearch.randomizedtesting.annotations.Listeners; /** * Test listeners on suite. */ public class TestListenersAnnotation extends WithNestedTestClass { public static List buffer = new ArrayList(); public static class NoopListener extends RunListener { } public static class BufferAppendListener extends RunListener { public void testRunStarted(Description description) throws Exception { buffer.add("run started: " + description.getMethodName()); } public void testStarted(Description description) throws Exception { buffer.add("test started: " + description.getMethodName()); } @Override public void testFinished(Description description) throws Exception { buffer.add("test finished: " + description.getMethodName()); } @Override public void testAssumptionFailure(Failure failure) { buffer.add("assumption failed: " + failure.getDescription().getMethodName()); } @Override public void testIgnored(Description description) throws Exception { buffer.add("test ignored: " + description.getMethodName()); } @Override public void testFailure(Failure failure) throws Exception { buffer.add("failure: " + failure.getDescription().getMethodName()); } @Override public void testRunFinished(Result result) throws Exception { buffer.add("run finished: " + result.getRunCount()); } } @Listeners({BufferAppendListener.class}) public static class Nested1 extends RandomizedTest { } @Listeners({NoopListener.class}) public static class Nested2 extends Nested1 { @Test @Ignore public void ignored() { } @Test public void passing() throws Exception { } @Test public void failing() throws Exception { assumeRunningNested(); Assert.fail(); } @Test public void assumptionFailing() throws Exception { assumeRunningNested(); Assume.assumeTrue(false); } } @Test public void checkListeners() { JUnitCore.runClasses(Nested2.class); // Perhaps this is overly simple, but we just want to know that it executed. Assert.assertTrue(buffer.size() > 0); } } TestMacSysThreads.java000066400000000000000000000021251235451432000401470ustar00rootroot00000000000000randomizedtesting-release-2.1.6/randomized-runner/src/test/java/com/carrotsearch/randomizedtestingpackage com.carrotsearch.randomizedtesting; import java.lang.management.ManagementFactory; import javax.management.MBeanServer; import junit.framework.Assert; import org.junit.Test; import org.junit.runner.JUnitCore; import org.junit.runner.Result; import com.carrotsearch.randomizedtesting.annotations.ThreadLeakAction; import com.carrotsearch.randomizedtesting.annotations.ThreadLeakAction.Action; import com.carrotsearch.randomizedtesting.annotations.ThreadLeakScope; import com.carrotsearch.randomizedtesting.annotations.ThreadLeakScope.Scope; /** * Test Mac system threads. */ public class TestMacSysThreads extends WithNestedTestClass { @ThreadLeakScope(Scope.SUITE) @ThreadLeakAction({Action.WARN}) public static class Nested extends RandomizedTest { @Test public void testMethod1() { MBeanServer mb = ManagementFactory.getPlatformMBeanServer(); mb.getMBeanCount(); RandomizedTest.sleep(5000); } } @Test public void testSuccessful() { Result result = JUnitCore.runClasses(Nested.class); Assert.assertEquals(0, result.getFailureCount()); } } TestManyThreadsOOM.java000066400000000000000000000016021235451432000402260ustar00rootroot00000000000000randomizedtesting-release-2.1.6/randomized-runner/src/test/java/com/carrotsearch/randomizedtestingpackage com.carrotsearch.randomizedtesting; import java.util.Random; import org.junit.Test; import com.carrotsearch.randomizedtesting.annotations.Repeat; /** * Make sure we don't OOM even if we recreate many, many threads during a test/ suite. */ public class TestManyThreadsOOM extends RandomizedTest { volatile int guard; @Test @Repeat(iterations = 10) public void testSpawnManyThreads() throws Exception { // create threads sequentially, attaching a big blob of data to each, then // touch the context from within a thread and die. for (int i = 0; i < 500; i++) { final Thread t = new Thread() { final byte [] hold = new byte [1024 * 1024 * 10]; public void run() { Random rnd = RandomizedContext.current().getRandom(); guard += rnd.nextInt() + hold.length; } }; t.start(); t.join(); } } } TestNightlyMode.java000066400000000000000000000033771235451432000376720ustar00rootroot00000000000000randomizedtesting-release-2.1.6/randomized-runner/src/test/java/com/carrotsearch/randomizedtestingpackage com.carrotsearch.randomizedtesting; import org.junit.After; import org.junit.Assert; import org.junit.Before; import org.junit.Test; import org.junit.runner.JUnitCore; import org.junit.runner.Result; import com.carrotsearch.randomizedtesting.annotations.Nightly; import com.carrotsearch.randomizedtesting.annotations.TestGroup; /** * Nightly mode checks. */ public class TestNightlyMode extends WithNestedTestClass { public static class Nested extends RandomizedTest { @Test public void passOnNightlyOnly() { assumeRunningNested(); assertTrue(isNightly()); } @Test @Nightly("Nightly only test case.") public void nightlyOnly() throws Exception { } } @Test public void invalidValueNightly() { System.setProperty(TestGroup.Utilities.getSysProperty(Nightly.class), "invalid-value"); Result result = JUnitCore.runClasses(Nested.class); Assert.assertEquals(2, result.getRunCount()); Assert.assertEquals(1, result.getFailureCount()); Assert.assertEquals(1, result.getIgnoreCount()); } @Test public void nightly() { System.setProperty(TestGroup.Utilities.getSysProperty(Nightly.class), "yes"); Result result = JUnitCore.runClasses(Nested.class); Assert.assertEquals(2, result.getRunCount()); Assert.assertEquals(0, result.getFailureCount()); } @Test public void dailyDefault() { Result result = JUnitCore.runClasses(Nested.class); Assert.assertEquals(2, result.getRunCount()); Assert.assertEquals(1, result.getFailureCount()); Assert.assertEquals(1, result.getIgnoreCount()); } @Before public void cleanupBefore() { cleanupAfter(); } @After public void cleanupAfter() { System.clearProperty(TestGroup.Utilities.getSysProperty(Nightly.class)); } } TestOutOfScopeRandomUse.java000066400000000000000000000071321235451432000413040ustar00rootroot00000000000000randomizedtesting-release-2.1.6/randomized-runner/src/test/java/com/carrotsearch/randomizedtestingpackage com.carrotsearch.randomizedtesting; import java.util.Random; import junit.framework.Assert; import org.junit.AfterClass; import org.junit.Before; import org.junit.BeforeClass; import org.junit.Test; import org.junit.runner.JUnitCore; import org.junit.runner.Result; import com.carrotsearch.randomizedtesting.annotations.Timeout; /** * Check out of scope {@link Random} use. */ public class TestOutOfScopeRandomUse extends WithNestedTestClass { public static class Nested extends RandomizedTest { static Random instanceRandom; static Random beforeHookRandom; static Random staticContextRandom; volatile static Random otherThreadRandom; @BeforeClass public static void beforeClass() throws Exception { assumeRunningNested(); instanceRandom = null; staticContextRandom = getRandom(); // Should be able to use the random we've acquired for the static context. staticContextRandom.nextBoolean(); Thread t = new Thread() { public void run() { otherThreadRandom = getRandom(); } }; t.start(); t.join(); } @AfterClass public static void afterClass() { if (!isRunningNested()) { return; } // Again should be able to use the random we've acquired for the static context. staticContextRandom.nextBoolean(); } @Before public void before() { beforeHookRandom = getRandom(); } private void touchRandom() { assumeRunningNested(); // We shouldn't be able to reach to some other thread's random for which // the context is still valid. try { otherThreadRandom.nextBoolean(); fail("Shouldn't be able to use another thread's Random."); } catch (IllegalStateException e) { // Expected. } // We should always be able to reach to @Before hook initialized Random. beforeHookRandom.nextBoolean(); // Check if we're the first method or the latter methods. if (instanceRandom == null) { instanceRandom = getRandom(); } else { // for anything not-first, we shouldn't be able to reuse first random anymore. try { instanceRandom.nextBoolean(); fail("Shouldn't be able to use another test's Random."); } catch (IllegalStateException e) { // Expected. } } } @Test public void method1() throws Exception { touchRandom(); } @Test @Timeout(millis = 2000) public void method2() throws Exception { touchRandom(); // We shouldn't be able to use the static random because timeouting tests // are executed in their own thread and before and after class hooks are // dispatched in their own thread to allow termination/ interruptions. try { staticContextRandom.nextBoolean(); fail("Shouldn't be able to use static context thread's Random."); } catch (IllegalStateException e) { // Expected. } } } @Test public void testCrossTestCaseIsolation() throws Throwable { Result runClasses = JUnitCore.runClasses(Nested.class); if (!runClasses.getFailures().isEmpty()) { throw runClasses.getFailures().get(0).getException(); } Assert.assertEquals(0, runClasses.getFailureCount()); } @Test public void testCrossTestSuiteIsolation() { JUnitCore.runClasses(Nested.class); try { Nested.staticContextRandom.nextBoolean(); Assert.fail("Shouldn't be able to use another suite's Random."); } catch (IllegalStateException e) { // Expected. } } } TestOverlappingMethodProviders.java000066400000000000000000000012201235451432000427550ustar00rootroot00000000000000randomizedtesting-release-2.1.6/randomized-runner/src/test/java/com/carrotsearch/randomizedtestingpackage com.carrotsearch.randomizedtesting; import org.junit.Assert; import org.junit.Test; import org.junit.runner.JUnitCore; import org.junit.runner.Result; import com.carrotsearch.randomizedtesting.annotations.TestMethodProviders; public class TestOverlappingMethodProviders { @TestMethodProviders({ JUnit4MethodProvider.class, JUnit3MethodProvider.class }) public static class Base { @Test public void testMe() {} } @Test public void testSingleMethod() throws Exception { Result r = new JUnitCore().run(Base.class); Assert.assertEquals(0, r.getFailureCount()); Assert.assertEquals(1, r.getRunCount()); } } TestOverridingDefaultExceptionHandler.java000066400000000000000000000043051235451432000442310ustar00rootroot00000000000000randomizedtesting-release-2.1.6/randomized-runner/src/test/java/com/carrotsearch/randomizedtestingpackage com.carrotsearch.randomizedtesting; import java.lang.Thread.UncaughtExceptionHandler; import java.util.List; import org.fest.assertions.api.Assertions; import org.junit.AfterClass; import org.junit.BeforeClass; import org.junit.Test; import org.junit.runner.JUnitCore; import com.google.common.collect.Lists; public class TestOverridingDefaultExceptionHandler extends WithNestedTestClass { static List throwableMessages = Lists.newCopyOnWriteArrayList(); @SuppressWarnings("serial") public static class TestException extends RuntimeException { public TestException(String msg) { super(msg); } } public static class Nested extends RandomizedTest { private static UncaughtExceptionHandler defaultHandler; @BeforeClass public static void beforeClass() { defaultHandler = Thread.getDefaultUncaughtExceptionHandler(); Thread.setDefaultUncaughtExceptionHandler(new UncaughtExceptionHandler() { public void uncaughtException(Thread t, Throwable e) { if (e instanceof TestException) { throwableMessages.add(e.getMessage()); } else { defaultHandler.uncaughtException(t, e); } } }); } @AfterClass public static void afterClass() { Thread.setDefaultUncaughtExceptionHandler(defaultHandler); } @Test public void exceptionFromChildThread() throws Exception { Thread t = new Thread() { @Override public void run() { throw new TestException("exceptionFromChildThread"); } }; t.start(); t.join(); } @Test public void exceptionFromSubGroup() throws Exception { ThreadGroup subgroup = new ThreadGroup("subgroup"); Thread t = new Thread(subgroup, new Runnable() { @Override public void run() { throw new TestException("exceptionFromSubGroup"); } }); t.start(); t.join(); } } @Test public void testHandlerPropagation() { JUnitCore.runClasses(Nested.class); Assertions.assertThat(throwableMessages).contains("exceptionFromChildThread"); Assertions.assertThat(throwableMessages).contains("exceptionFromSubGroup"); } } TestParameterized.java000066400000000000000000000056411235451432000402370ustar00rootroot00000000000000randomizedtesting-release-2.1.6/randomized-runner/src/test/java/com/carrotsearch/randomizedtestingpackage com.carrotsearch.randomizedtesting; import java.util.Arrays; import java.util.Collections; import org.junit.Assert; import org.junit.Test; import org.junit.runner.JUnitCore; import org.junit.runner.Result; import com.carrotsearch.randomizedtesting.annotations.Name; import com.carrotsearch.randomizedtesting.annotations.ParametersFactory; import com.carrotsearch.randomizedtesting.annotations.Repeat; import com.carrotsearch.randomizedtesting.annotations.Seed; import com.carrotsearch.randomizedtesting.annotations.Seeds; public class TestParameterized extends WithNestedTestClass { public static class Nested extends RandomizedTest { public Nested(@Name("value") int value, @Name("string") String v) { } @Test @Repeat(iterations = 3) public void testOne() { } @Test public void testTwo() { } @Seeds({@Seed("deadbeef"), @Seed("cafebabe")}) @Test @Repeat(iterations = 2, useConstantSeed = true) public void testThree() { } @ParametersFactory public static Iterable parameters() { return Arrays.asList($$( $(1, "abc"), $(2, "def"))); } } @Test public void testWithRepeatsAndSeeds() { Result result = JUnitCore.runClasses(Nested.class); Assert.assertEquals(16, result.getRunCount()); } public static class Nested2 extends RandomizedTest { public Nested2(@Name("paramName") int value) { } @Test public void failing() { assumeRunningNested(); fail(); } @ParametersFactory public static Iterable parameters() { assumeRunningNested(); return Arrays.asList($$($("xyz"))); } } @Test public void testNameAnnotation() { Result result = JUnitCore.runClasses(Nested2.class); Assert.assertEquals(1, result.getFailureCount()); Assert.assertTrue(result.getFailures().get(0).getDescription().getMethodName().contains("paramName=xyz")); Assert.assertEquals("failing", RandomizedRunner.methodName(result.getFailures().get(0).getDescription())); } public static class Nested3 extends Nested2 { public Nested3(@Name("paramName") int value) { super(value); } @ParametersFactory public static Iterable parameters() { return Collections.emptyList(); } } public static class Nested4 extends Nested3 { public Nested4(@Name("paramName") int value) { super(value); } @ParametersFactory public static Iterable parameters() { assumeTrue(false); throw new RuntimeException(); } } @Test public void testEmptyParamsList() { Result result = JUnitCore.runClasses(Nested3.class); Assert.assertEquals(0, result.getRunCount()); Assert.assertEquals(0, result.getIgnoreCount()); result = JUnitCore.runClasses(Nested4.class); Assert.assertEquals(0, result.getRunCount()); Assert.assertEquals(0, result.getIgnoreCount()); } } TestParameterizedShufflesOrder.java000066400000000000000000000041661235451432000427340ustar00rootroot00000000000000randomizedtesting-release-2.1.6/randomized-runner/src/test/java/com/carrotsearch/randomizedtestingpackage com.carrotsearch.randomizedtesting; import java.util.ArrayList; import java.util.HashSet; import java.util.List; import java.util.Set; import org.fest.assertions.api.Assertions; import org.junit.Test; import org.junit.runner.JUnitCore; import org.junit.runner.Result; import com.carrotsearch.randomizedtesting.annotations.ParametersFactory; public class TestParameterizedShufflesOrder extends WithNestedTestClass { static StringBuilder buf; public static class Base extends RandomizedTest { private final int value; public Base(int value) { this.value = value; } @Test public void testFoo() { buf.append(value).append(","); } } public static class NoShuffle extends Base { public NoShuffle(int value) { super(value); } @ParametersFactory(shuffle = false) public static Iterable parameters() { List params = new ArrayList(); for (int i = 0; i < 10; i++) { params.add($(i)); } return params; } } public static class WithShuffle extends Base { public WithShuffle(int value) { super(value); } @ParametersFactory() public static Iterable parameters() { List params = new ArrayList(); for (int i = 0; i < 10; i++) { params.add($(i)); } return params; } } @Test public void testWithoutShuffle() { Set runs = new HashSet(); for (int i = 0; i < 10; i++) { buf = new StringBuilder(); Result result = JUnitCore.runClasses(NoShuffle.class); Assertions.assertThat(result.wasSuccessful()).isTrue(); runs.add(buf.toString()); } Assertions.assertThat(runs).hasSize(1); } @Test public void testWithShuffle() { Set runs = new HashSet(); int iters = 10; for (int i = 0; i < iters; i++) { buf = new StringBuilder(); Result result = JUnitCore.runClasses(WithShuffle.class); Assertions.assertThat(result.wasSuccessful()).isTrue(); runs.add(buf.toString()); } Assertions.assertThat(runs).hasSize(iters); } } TestRandomInStaticInitializer.java000066400000000000000000000007341235451432000425240ustar00rootroot00000000000000randomizedtesting-release-2.1.6/randomized-runner/src/test/java/com/carrotsearch/randomizedtestingpackage com.carrotsearch.randomizedtesting; import java.util.Random; import org.junit.Test; /** * Check out of scope {@link Random} use. */ public class TestRandomInStaticInitializer extends RandomizedTest { static boolean wasOutOfScope; static { try { RandomizedContext.current(); } catch (IllegalStateException e) { wasOutOfScope = true; } } @Test public void testStaticInitializerOutOfScope() { assertTrue(wasOutOfScope); } } TestRandomizedTest.java000066400000000000000000000141021235451432000403670ustar00rootroot00000000000000randomizedtesting-release-2.1.6/randomized-runner/src/test/java/com/carrotsearch/randomizedtestingpackage com.carrotsearch.randomizedtesting; import java.io.File; import java.io.FileOutputStream; import java.io.IOException; import java.net.ServerSocket; import java.util.ArrayList; import java.util.Collections; import java.util.List; import org.junit.Test; import org.junit.internal.AssumptionViolatedException; public class TestRandomizedTest extends RandomizedTest { @Test public void testRandomInt() { boolean [] array = new boolean [10]; for (int i = 0; i < 10000; i++) array[randomInt(array.length - 1)] = true; for (boolean b: array) assertTrue(b); } @Test public void testRandomIntBetween() { boolean [] array = new boolean [10]; for (int i = 0; i < 10000; i++) array[randomIntBetween(0, array.length - 1)] = true; for (boolean b: array) assertTrue(b); } @Test public void testAtLeast() { assertEquals(atLeast(Integer.MAX_VALUE), Integer.MAX_VALUE); int v = randomIntBetween(0, Integer.MAX_VALUE); for (int i = 0; i < 10000; i++) assertTrue(atLeast(v) >= v); } @Test public void testAtMost() { assertEquals(atMost(0), 0); int v = randomIntBetween(0, Integer.MAX_VALUE); for (int i = 0; i < 10000; i++) assertTrue(atMost(v) <= v); } @Test public void testRandomIntBetweenBoundaryCases() { for (int i = 0; i < 10000; i++) { int j = randomIntBetween(0, Integer.MAX_VALUE); assertTrue(j >= 0 && j <= Integer.MAX_VALUE); // This must fall in range, but nonetheless randomIntBetween(Integer.MIN_VALUE, Integer.MAX_VALUE); } } @Test public void testRandomFromArray() { try { randomFrom(new Object [] {}); fail(); } catch (IllegalArgumentException e) { // expected. } Integer [] ints = new Integer [10]; for (int i = 0; i < ints.length; i++) ints[i] = i; for (int i = 0; i < 10000; i++) { Integer j = randomFrom(ints); if (j != null) { ints[j] = null; } } for (int i = 0; i < ints.length; i++) assertTrue(ints[i] == null); } @Test public void testRandomFromList() { try { randomFrom(Collections.emptyList()); fail(); } catch (IllegalArgumentException e) { // expected. } List ints = new ArrayList(); for (int i = 0; i < 10; i++) ints.add(i); for (int i = 0; i < 10000; i++) { Integer j = randomFrom(ints); if (j != null) { ints.set(j, null); } } for (int i = 0; i < ints.size(); i++) assertTrue(ints.get(i) == null); } @Test public void testNewTempDir() { for (int i = 0; i < 10; i++) { File dir = newTempDir(); assertNotNull(dir); assertTrue(dir.isDirectory()); assertTrue(dir.canWrite()); assertTrue(dir.canRead()); assertTrue(dir.canExecute()); assertEquals(0, dir.listFiles().length); } } @Test public void testNewTempFile() throws IOException { for (int i = 0; i < 10; i++) { File file = newTempFile(); assertNotNull(file); assertTrue(file.isFile()); assertTrue(file.canWrite()); assertTrue(file.canRead()); assertTrue(file.getName().indexOf(' ') >= 0); new FileOutputStream(file).close(); } } @Test public void testRandomLocale() { assertNotNull(randomLocale()); } @Test public void testRandomTimeZone() { assertNotNull(randomTimeZone()); } @Test public void testRandomAsciiOfLength() { assertTrue(randomAsciiOfLength(0).isEmpty()); for (int i = 0; i < 1000; i++) { int maxLength = randomInt(20); String str = randomAsciiOfLength(maxLength); assertTrue(str.matches("[a-zA-Z0-9]*")); assertTrue(str.length() <= maxLength); } } @Test public void testRandomUnicodeOfLength() { for (int i = 0; i < 1000; i++) { int maxLength = randomInt(20); String str = randomUnicodeOfLength(maxLength); assertTrue(str.length() + " " + maxLength, str.length() <= maxLength); } } @Test public void testRandomRealisticUnicodeOfLength() { assertTrue(randomRealisticUnicodeOfLength(0).isEmpty()); assertTrue(randomRealisticUnicodeOfCodepointLength(0).isEmpty()); for (int i = 0; i < 1000; i++) { int minLength = randomInt(20); int maxLength = minLength + randomInt(20); String str = randomRealisticUnicodeOfCodepointLength(maxLength); int codepoints = countCodepoints(str); assertTrue(codepoints <= maxLength); str = randomRealisticUnicodeOfCodepointLengthBetween(minLength, maxLength); codepoints = countCodepoints(str); assertTrue(codepoints >= minLength); assertTrue(codepoints <= maxLength); } } private static int countCodepoints(String str) { return str.codePointCount(0, str.length()); } @Test public void testAssumeTrue() { String message = randomUnicodeOfLength(10); try { assumeTrue(message, false); } catch (AssumptionViolatedException e) { assertTrue(e.getMessage().contains(message)); } } @Test public void testAssumeNoException() { String message = randomUnicodeOfLength(10); Throwable t = new Throwable(); try { assumeNoException(message, t); } catch (AssumptionViolatedException e) { assertTrue(e.getMessage().contains(message)); assertSame(t, e.getCause()); } } @Test public void testIterations() { assertEquals(0, iterations(0, 0)); assertEquals(Integer.MAX_VALUE, iterations(Integer.MAX_VALUE, Integer.MAX_VALUE)); for (int i = 0; i < iterations(1, 1000); i++) { int j = iterations(0, 100); assertTrue(j >= 0 && j <= 100); } } @Test public void testNewServerSocket() throws IOException { ServerSocket socket = newServerSocket(LifecycleScope.TEST); socket.close(); } @Test public void testRarely() throws IOException { int rarely = 0; int calls = 100000; for (int i = 0; i < calls; i++) { if (rarely()) rarely++; } double rf = rarely / (double) calls * 100; assertTrue("rarely should be > 5% & < 15%: " + rf, rf > 5 && rf < 15); } } TestRepeatTestWithComplexDescription.java000066400000000000000000000045271235451432000441150ustar00rootroot00000000000000randomizedtesting-release-2.1.6/randomized-runner/src/test/java/com/carrotsearch/randomizedtestingpackage com.carrotsearch.randomizedtesting; import java.util.ArrayList; import java.util.List; import org.fest.assertions.api.Assertions; import org.junit.Rule; import org.junit.Test; import org.junit.runner.Description; import org.junit.runner.JUnitCore; import org.junit.runner.Result; import org.junit.runner.notification.RunListener; import com.carrotsearch.randomizedtesting.annotations.Listeners; import com.carrotsearch.randomizedtesting.annotations.Name; import com.carrotsearch.randomizedtesting.annotations.ParametersFactory; import com.carrotsearch.randomizedtesting.annotations.Repeat; import com.carrotsearch.randomizedtesting.annotations.Seed; import com.carrotsearch.randomizedtesting.annotations.Seeds; import com.carrotsearch.randomizedtesting.rules.SystemPropertiesRestoreRule; /** */ public class TestRepeatTestWithComplexDescription extends WithNestedTestClass { @Rule public SystemPropertiesRestoreRule restoreProperties = new SystemPropertiesRestoreRule(); static ArrayList buf; public static class CaptureFailuresListener extends RunListener { @Override public void testStarted(Description description) throws Exception { buf.add(description.getMethodName()); } } @Seed("deadbeef") @Listeners({CaptureFailuresListener.class}) public static class Nested extends RandomizedTest { public Nested(@Name("value") String value) { } @Test @Seeds({@Seed(), @Seed("deadbeef")}) @Repeat(iterations = 5, useConstantSeed = false) public void testFoo() {} @Test public void testBar() {} @ParametersFactory() public static Iterable parameters() { List params = new ArrayList(); params.add($("")); params.add($("a/b/c")); params.add($("\\")); params.add($("$[]{}\\")); return params; } } @Test public void checkFilteringByName() { // Collect all test names first. buf = new ArrayList(); JUnitCore.runClasses(Nested.class); for (String testName : buf) { buf = new ArrayList(); System.setProperty(SysGlobals.SYSPROP_TESTMETHOD(), testName); Result result = JUnitCore.runClasses(Nested.class); Assertions.assertThat(result.wasSuccessful()).as(result.getFailures().toString()).isTrue(); Assertions.assertThat(buf).containsOnly(testName); } } } TestResourceDisposal.java000066400000000000000000000060451235451432000407300ustar00rootroot00000000000000randomizedtesting-release-2.1.6/randomized-runner/src/test/java/com/carrotsearch/randomizedtestingpackage com.carrotsearch.randomizedtesting; import java.io.Closeable; import java.io.IOException; import java.util.ArrayList; import java.util.List; import junit.framework.Assert; import org.junit.*; import org.junit.runner.JUnitCore; import org.junit.runner.Result; /** * Check resource disposal facilities. */ public class TestResourceDisposal extends WithNestedTestClass { static class DummyCloseable implements Closeable { public boolean closed; public void close() throws IOException { if (closed) throw new IOException(); closed = true; } } public static class Nested extends RandomizedTest { static List testScope = new ArrayList(); static List suiteScope = new ArrayList(); static boolean allTestScopeClosed; static boolean allSuiteScopeOpen; @BeforeClass public static void clean() { testScope.clear(); suiteScope.clear(); suiteScope.add(closeAfterSuite(new DummyCloseable())); } @AfterClass public static void afterClass() { allTestScopeClosed = true; for (DummyCloseable c : Nested.testScope) { if (!c.closed) allTestScopeClosed = false; } allSuiteScopeOpen = true; for (DummyCloseable c : Nested.suiteScope) { if (c.closed) allSuiteScopeOpen = false; } } @Test public void testScopeResource() { assumeRunningNested(); testScope.add(closeAfterTest(new DummyCloseable())); testScope.add(closeAfterTest(new DummyCloseable())); } @Test public void testScopeResourceWithFailures() { assumeRunningNested(); testScope.add(closeAfterTest(new DummyCloseable())); testScope.add(closeAfterTest(new DummyCloseable())); throw new RuntimeException(); } @Test public void suiteScopeFromTest() { assumeRunningNested(); suiteScope.add(closeAfterSuite(new DummyCloseable())); suiteScope.add(closeAfterSuite(new DummyCloseable())); } } @Test public void testResourceDisposalTestScope() { Result r = JUnitCore.runClasses(Nested.class); for (DummyCloseable c : Nested.testScope) { Assert.assertTrue(c.closed); } Assert.assertEquals(1, r.getFailureCount()); Assert.assertTrue(Nested.allTestScopeClosed); } @Test public void testResourceDisposalSuiteScope() { JUnitCore.runClasses(Nested.class); for (DummyCloseable c : Nested.suiteScope) { Assert.assertTrue(c.closed); } Assert.assertTrue(Nested.allSuiteScopeOpen); } public static class Nested2 extends RandomizedTest { @Test public void testScope() { assumeRunningNested(); closeAfterTest(closeAfterTest(new DummyCloseable())); } } @Test public void testFailedDisposalBreaksTestCase() { Result r = JUnitCore.runClasses(Nested2.class); Assert.assertEquals(1, r.getRunCount()); Assert.assertEquals(1, r.getFailureCount()); Assert.assertTrue(r.getFailures().get(0).getException() instanceof ResourceDisposalError); } } TestRules.java000066400000000000000000000060571235451432000365370ustar00rootroot00000000000000randomizedtesting-release-2.1.6/randomized-runner/src/test/java/com/carrotsearch/randomizedtestingpackage com.carrotsearch.randomizedtesting; import java.util.List; import org.junit.*; import org.junit.rules.*; import org.junit.runner.*; import org.junit.runners.model.FrameworkMethod; import org.junit.runners.model.Statement; import com.google.common.collect.Lists; /** * {@link Rule} and {@link MethodRule} support. */ @SuppressWarnings({"deprecation", "javadoc"}) public class TestRules extends WithNestedTestClass { static List order; public static class MethodRuleSupport { @Rule public MethodRule rule1 = new MethodRule() { public Statement apply(final Statement base, FrameworkMethod method, Object target) { return new Statement() { @Override public void evaluate() throws Throwable { assumeRunningNested(); order.add("rule1-before"); base.evaluate(); order.add("rule1-after"); } }; } }; @Test public void passing() { order.add("passing"); } } public static class SimpleRule implements TestRule { private String msg; public SimpleRule(String msg) { this.msg = msg; } @Override public Statement apply(final Statement base, Description description) { return new Statement() { public void evaluate() throws Throwable { assumeRunningNested(); order.add(msg + "-before"); try { base.evaluate(); } finally { order.add(msg + "-after"); } } }; } } public static class NewRuleSupportPassing { @Rule public TestRule rule1 = RuleChain .outerRule(new SimpleRule("outer")) .around(new SimpleRule("inner")); @Test public void passing() { order.add("passing"); } } public static class NewRuleSupportFailing { @Rule public TestRule rule1 = RuleChain .outerRule(new SimpleRule("outer")) .around(new SimpleRule("inner")); @Test public void failing() { order.add("failing"); throw new RuntimeException(); } } public static class NewRuleSupportIgnored { @Rule public TestRule rule1 = RuleChain .outerRule(new SimpleRule("outer")) .around(new SimpleRule("inner")); @Test @Ignore public void ignored() { order.add("ignored"); throw new RuntimeException(); } } @Test public void checkOldMethodRules() throws Exception { assertSameExecution(MethodRuleSupport.class); } @Test public void checkNewTestRules() throws Exception { assertSameExecution(NewRuleSupportPassing.class); assertSameExecution(NewRuleSupportFailing.class); assertSameExecution(NewRuleSupportIgnored.class); } private void assertSameExecution(Class clazz) throws Exception { order = Lists.newArrayList(); JUnitCore.runClasses(clazz); List order1 = order; order = Lists.newArrayList(); new JUnitCore().run(Request.runner(new RandomizedRunner(clazz))); List order2 = order; order = null; Assert.assertEquals(order1, order2); } } TestSeedDecorator.java000066400000000000000000000045421235451432000401650ustar00rootroot00000000000000randomizedtesting-release-2.1.6/randomized-runner/src/test/java/com/carrotsearch/randomizedtestingpackage com.carrotsearch.randomizedtesting; import java.util.*; import org.fest.assertions.api.Assertions; import org.junit.*; import org.junit.runner.JUnitCore; import org.junit.runner.RunWith; import com.carrotsearch.randomizedtesting.annotations.SeedDecorators; import com.carrotsearch.randomizedtesting.generators.RandomStrings; /** * Test seed decorators. */ public class TestSeedDecorator extends WithNestedTestClass { private static List runnerSeeds = new ArrayList(); private static List strings = new ArrayList(); @RunWith(RandomizedRunner.class) public static class Nested1 { @BeforeClass public static void generateSequence() { strings.add( RandomStrings.randomAsciiOfLength(RandomizedContext.current().getRandom(), 200)); } @Test public void method1() { assumeRunningNested(); runnerSeeds.add(RandomizedContext.current().getRunnerSeedAsString()); } } public static class Nested2 extends Nested1 { } @SeedDecorators({ MixWithSuiteName.class }) public static class Nested3 extends Nested1 { } public static class Nested4 extends Nested3 { } @Before @After public void cleanup() { runnerSeeds.clear(); strings.clear(); System.clearProperty(SysGlobals.SYSPROP_RANDOM_SEED()); } @Test public void testDecoratedMaster() { String masterSeed = SeedUtils.formatSeed(new Random().nextLong()); System.setProperty(SysGlobals.SYSPROP_RANDOM_SEED(), masterSeed); // These classes should get a different master seed (perturbed by decorator). JUnitCore.runClasses(Nested1.class, Nested2.class, Nested3.class, Nested4.class); // All four classes get the same initial "runner" seed. Assert.assertEquals(4, runnerSeeds.size()); Assert.assertEquals(1, new HashSet(runnerSeeds).toArray().length); // @BeforeClass scope strings for Nested1 and Nested2 should be the same // because these classes share identical master seed. Assertions.assertThat(strings.get(1)).isEqualTo(strings.get(0)); // but Nested3 and Nested4 have a seed decorator so strings there // should be different. Assertions.assertThat(strings.get(2)).isNotEqualTo(strings.get(0)); Assertions.assertThat(strings.get(3)).isNotEqualTo(strings.get(0)); Assertions.assertThat(strings.get(2)).isNotEqualTo(strings.get(3)); } } TestSeedFixing.java000066400000000000000000000014111235451432000374570ustar00rootroot00000000000000randomizedtesting-release-2.1.6/randomized-runner/src/test/java/com/carrotsearch/randomizedtestingpackage com.carrotsearch.randomizedtesting; import static org.junit.Assert.assertEquals; import org.fest.assertions.api.Assertions; import org.junit.BeforeClass; import org.junit.Test; import org.junit.runner.RunWith; import com.carrotsearch.randomizedtesting.annotations.Seed; /** * Seed fixing for static fixtures and/or methods using annotations. */ @RunWith(RandomizedRunner.class) @Seed("deadbeef") public class TestSeedFixing { @BeforeClass public static void beforeClass() { assertEquals(0xdeadbeefL, RandomizedContext.current().getRandomness().getSeed()); } @Seed("cafebabe") @Test public void dummy() { Assertions .assertThat(Long.toHexString(RandomizedContext.current().getRandomness().getSeed())) .isEqualTo("cafebabe"); } } TestSeedFixingWithProperties.java000066400000000000000000000051001235451432000423670ustar00rootroot00000000000000randomizedtesting-release-2.1.6/randomized-runner/src/test/java/com/carrotsearch/randomizedtestingpackage com.carrotsearch.randomizedtesting; import java.util.ArrayList; import java.util.Arrays; import java.util.List; import org.junit.After; import org.junit.Before; import org.junit.BeforeClass; import org.junit.Test; import org.junit.runner.JUnitCore; import org.junit.runner.Result; import org.junit.runner.RunWith; import com.carrotsearch.randomizedtesting.RandomizedContext; import com.carrotsearch.randomizedtesting.RandomizedRunner; import static com.carrotsearch.randomizedtesting.SysGlobals.*; import static org.junit.Assert.*; /** * Seed fixing for static fixtures and/or methods using system properties. */ public class TestSeedFixingWithProperties extends WithNestedTestClass { static List seeds = new ArrayList(); @RunWith(RandomizedRunner.class) public static class Nested { @BeforeClass public static void staticFixture() { seeds.add(RandomizedContext.current().getRandomness().getSeed()); } @Test public void testMethod() { seeds.add(RandomizedContext.current().getRandomness().getSeed()); } } /** * Combined seed: fixing everything: the runner, method and any repetitions. */ @Test public void testRunnerAndMethodProperty() { System.setProperty(SYSPROP_RANDOM_SEED(), "deadbeef:cafebabe"); System.setProperty(SYSPROP_ITERATIONS(), "3"); JUnitCore.runClasses(Nested.class); assertEquals(Arrays.asList(0xdeadbeefL, 0xcafebabeL, 0xcafebabeL, 0xcafebabeL), seeds); } /** * Runner seed fixing only (methods have predictable pseudo-random seeds derived from * the runner). */ @Test public void testFixedRunnerPropertyOnly() { System.setProperty(SYSPROP_RANDOM_SEED(), "deadbeef"); System.setProperty(SYSPROP_ITERATIONS(), "3"); Result result = JUnitCore.runClasses(Nested.class); assertEquals(3, result.getRunCount()); assertEquals(0xdeadbeefL, seeds.get(0).longValue()); // _very_ slim chances of this actually being true... assertFalse( seeds.get(0).longValue() == seeds.get(1).longValue() && seeds.get(1).longValue() == seeds.get(2).longValue()); // We should have the same randomized seeds on methods for the same runner seed, // so check if this is indeed true. List copy = new ArrayList(seeds); seeds.clear(); JUnitCore.runClasses(Nested.class); assertEquals(copy, seeds); } @Before public void cleanupBefore() { cleanupAfter(); } @After public void cleanupAfter() { System.clearProperty(SYSPROP_ITERATIONS()); System.clearProperty(SYSPROP_RANDOM_SEED()); seeds.clear(); } } TestSeedParameterOptional.java000066400000000000000000000030151235451432000416630ustar00rootroot00000000000000randomizedtesting-release-2.1.6/randomized-runner/src/test/java/com/carrotsearch/randomizedtestingpackage com.carrotsearch.randomizedtesting; import java.util.HashSet; import junit.framework.Assert; import org.junit.Test; import org.junit.runner.*; import org.junit.runner.notification.RunListener; import com.carrotsearch.randomizedtesting.annotations.*; /** * Check if seed parameter is optional if no repetitions * of the test are requested. */ public class TestSeedParameterOptional extends WithNestedTestClass { public static class Nested extends RandomizedTest { @Seeds({ @Seed("deadbeef"), @Seed("cafebabe"), @Seed // Adds a randomized execution too. }) @Test @Repeat(iterations = 2, useConstantSeed = true) public void method1() { } @Seed("cafebabe") @Test public void method2() { } @Test public void method3() { } } @Test public void checkNames() { final HashSet tests = new HashSet(); JUnitCore junit = new JUnitCore(); junit.addListener(new RunListener() { @Override public void testStarted(Description description) throws Exception { tests.add(description.getMethodName()); } }); junit.run(Nested.class); // Single repetitions, no seed parameter in test name. Assert.assertTrue(tests.contains("method2")); Assert.assertTrue(tests.contains("method3")); // Method 1 has 2x3 repetitions. int count = 0; for (String s : tests) { if (s.startsWith("method1")) { count++; } } Assert.assertEquals(6, count); } } TestSeedRepeatable.java000066400000000000000000000027251235451432000403100ustar00rootroot00000000000000randomizedtesting-release-2.1.6/randomized-runner/src/test/java/com/carrotsearch/randomizedtestingpackage com.carrotsearch.randomizedtesting; import static org.junit.Assert.assertEquals; import static org.junit.Assert.assertTrue; import java.util.HashMap; import java.util.Map; import org.junit.Test; import org.junit.runner.JUnitCore; import org.junit.runner.Result; import org.junit.runner.RunWith; import com.carrotsearch.randomizedtesting.annotations.Seed; public class TestSeedRepeatable { @Seed("deadbeef") @RunWith(RandomizedRunner.class) public static class Nested { static Map seeds = new HashMap(); @Test public void testMethod1() { checkSeed("method1"); } @Test public void testMethod2() { checkSeed("method2"); } private void checkSeed(String key) { final Object seed = RandomizedContext.current().getRandomness().getSeed(); if (seeds.containsKey(key)) { assertEquals(seeds.get(key), seed); } else { seeds.put(key, seed); } } } /** * Check if methods get the same seed on every run with a fixed runner's seed. */ @Test public void testSameMethodRandomnessWithFixedRunner() { Nested.seeds.clear(); Result result = JUnitCore.runClasses(Nested.class); assertTrue(result.getFailures().toString(), result.wasSuccessful()); result = JUnitCore.runClasses(Nested.class); assertTrue(result.wasSuccessful()); result = JUnitCore.runClasses(Nested.class); assertTrue(result.wasSuccessful()); } } TestSetSeedLocked.java000066400000000000000000000004361235451432000401160ustar00rootroot00000000000000randomizedtesting-release-2.1.6/randomized-runner/src/test/java/com/carrotsearch/randomizedtestingpackage com.carrotsearch.randomizedtesting; import org.junit.Test; public class TestSetSeedLocked extends RandomizedTest { @Test public void testMethod() { try { getRandom().setSeed(0); fail(); } catch (RuntimeException e) { // Ok, expected. } } } TestStackAugmentation.java000066400000000000000000000051111235451432000410540ustar00rootroot00000000000000randomizedtesting-release-2.1.6/randomized-runner/src/test/java/com/carrotsearch/randomizedtestingpackage com.carrotsearch.randomizedtesting; import static org.junit.Assert.*; import org.junit.*; import org.junit.runner.JUnitCore; import org.junit.runner.Result; import org.junit.runner.RunWith; import org.junit.runner.notification.Failure; import com.carrotsearch.randomizedtesting.annotations.Seed; /** * {@link RandomizedRunner} can augment stack traces to include seed info. Check * if it works. */ public class TestStackAugmentation extends WithNestedTestClass { @RunWith(RandomizedRunner.class) @Seed("deadbeef") public static class Nested { @Test @Seed("cafebabe") public void testMethod1() { assumeRunningNested(); // Throws a chained exception. try { throw new RuntimeException("Inner."); } catch (Exception e) { throw new Error("Outer.", e); } } } @Test public void testMethodLevel() { Result result = JUnitCore.runClasses(Nested.class); assertEquals(1, result.getFailureCount()); Failure f = result.getFailures().get(0); String seedFromThrowable = RandomizedRunner.seedFromThrowable(f.getException()); assertNotNull(seedFromThrowable); assertTrue("[DEADBEEF:CAFEBABE]".compareToIgnoreCase(seedFromThrowable) == 0); } @RunWith(RandomizedRunner.class) @Seed("deadbeef") public static class Nested2 { @BeforeClass public static void beforeClass() { assumeRunningNested(); throw new Error("beforeclass."); } @Test @Seed("cafebabe") public void testMethod1() { } } @Test public void testBeforeClass() { Result result = JUnitCore.runClasses(Nested2.class); assertEquals(1, result.getFailureCount()); Failure f = result.getFailures().get(0); String seedFromThrowable = RandomizedRunner.seedFromThrowable(f.getException()); assertNotNull(seedFromThrowable); assertTrue(f.getTrace(), "[DEADBEEF]".compareToIgnoreCase(seedFromThrowable) == 0); } @RunWith(RandomizedRunner.class) @Seed("deadbeef") public static class Nested3 { @AfterClass public static void afterClass() { assumeRunningNested(); throw new Error("afterclass."); } @Test @Seed("cafebabe") public void testMethod1() { } } @Test public void testAfterClass() { Result result = JUnitCore.runClasses(Nested3.class); assertEquals(1, result.getFailureCount()); Failure f = result.getFailures().get(0); String seedFromThrowable = RandomizedRunner.seedFromThrowable(f.getException()); assertNotNull(seedFromThrowable); assertTrue(f.getTrace(), "[DEADBEEF]".compareToIgnoreCase(seedFromThrowable) == 0); } } TestTestFiltering.java000066400000000000000000000040771235451432000402300ustar00rootroot00000000000000randomizedtesting-release-2.1.6/randomized-runner/src/test/java/com/carrotsearch/randomizedtestingpackage com.carrotsearch.randomizedtesting; import static com.carrotsearch.randomizedtesting.annotations.TestGroup.Utilities.getSysProperty; import java.lang.annotation.ElementType; import java.lang.annotation.Inherited; import java.lang.annotation.Retention; import java.lang.annotation.RetentionPolicy; import java.lang.annotation.Target; import org.fest.assertions.api.Assertions; import org.junit.Rule; import org.junit.Test; import org.junit.runner.JUnitCore; import org.junit.runner.Result; import com.carrotsearch.randomizedtesting.annotations.TestGroup; import com.carrotsearch.randomizedtesting.rules.SystemPropertiesRestoreRule; /** * Custom test groups. */ public class TestTestFiltering extends WithNestedTestClass { @Rule public SystemPropertiesRestoreRule restoreProperties = new SystemPropertiesRestoreRule(); @Retention(RetentionPolicy.RUNTIME) @Target({ElementType.METHOD, ElementType.TYPE}) @Inherited @TestGroup(enabled = false) public static @interface Foo { } public static class Nested1 extends RandomizedTest { @Test @Foo public void test1() { } } @Test public void filterVsRulePriority() { System.setProperty(getSysProperty(Foo.class), "false"); // Run @foo methods even though the group is disabled (by filtering rule). System.setProperty(SysGlobals.SYSPROP_TESTFILTER(), "@foo"); checkResult(JUnitCore.runClasses(Nested1.class), 1, 0, 0); // Don't run by default. System.setProperty(SysGlobals.SYSPROP_TESTFILTER(), ""); checkResult(JUnitCore.runClasses(Nested1.class), 1, 1, 0); // Run on default filter. System.setProperty(SysGlobals.SYSPROP_TESTFILTER(), "default"); checkResult(JUnitCore.runClasses(Nested1.class), 0, 0, 0); } private void checkResult(Result result, int run, int ignored, int failures) { Assertions.assertThat(result.getRunCount()).as("run count").isEqualTo(run); Assertions.assertThat(result.getIgnoreCount()).as("ignore count").isEqualTo(ignored); Assertions.assertThat(result.getFailureCount()).as("failure count").isEqualTo(failures); } } TestTestGroups.java000066400000000000000000000145161235451432000375630ustar00rootroot00000000000000randomizedtesting-release-2.1.6/randomized-runner/src/test/java/com/carrotsearch/randomizedtestingpackage com.carrotsearch.randomizedtesting; import java.lang.annotation.ElementType; import java.lang.annotation.Inherited; import java.lang.annotation.Retention; import java.lang.annotation.RetentionPolicy; import java.lang.annotation.Target; import org.fest.assertions.api.Assertions; import org.junit.AfterClass; import org.junit.Assert; import org.junit.BeforeClass; import org.junit.Test; import org.junit.runner.JUnitCore; import org.junit.runner.Result; import com.carrotsearch.randomizedtesting.annotations.Nightly; import com.carrotsearch.randomizedtesting.annotations.TestGroup; import static com.carrotsearch.randomizedtesting.annotations.TestGroup.Utilities.*; /** * Custom test groups. */ public class TestTestGroups extends WithNestedTestClass { @Retention(RetentionPolicy.RUNTIME) @Target({ElementType.METHOD, ElementType.TYPE}) @Inherited @TestGroup(enabled = true) public static @interface Group1 { } @Retention(RetentionPolicy.RUNTIME) @Target({ElementType.METHOD, ElementType.TYPE}) @Inherited @TestGroup(enabled = false, name = "abc", sysProperty = "custom.abc") public static @interface Group2 { } public static class Nested1 extends RandomizedTest { @Test @Group1 @Group2 public void test1() { } @BeforeClass public static void beforeClass() { beforeClassRan = true; } @AfterClass public static void afterClass() { afterClassRan = true; } } public static class Nested3 extends Nested1 { @Test public void testUnconditional() { } } @Group1 @Group2 public static class Nested2 extends RandomizedTest { @Test public void test1() { } @BeforeClass public static void beforeClass() { beforeClassRan = true; } @AfterClass public static void afterClass() { afterClassRan = true; } } public static boolean beforeClassRan; public static boolean afterClassRan; @Test public void checkDefaultNames() { Assert.assertEquals("group1", getGroupName(Group1.class)); Assert.assertEquals("abc", getGroupName(Group2.class)); Assert.assertEquals(SysGlobals.CURRENT_PREFIX() + ".group1", getSysProperty(Group1.class)); Assert.assertEquals("custom.abc", getSysProperty(Group2.class)); Assert.assertEquals(SysGlobals.CURRENT_PREFIX() + ".nightly", getSysProperty(Nightly.class)); Assert.assertEquals("nightly", getGroupName(Nightly.class)); } @Test public void groupsOnMethods() { String group1Property = getSysProperty(Group1.class); String group2Property = getSysProperty(Group2.class); try { afterClassRan = beforeClassRan = false; checkResult(JUnitCore.runClasses(Nested1.class), 1, 1, 0); Assert.assertFalse(afterClassRan); Assert.assertFalse(beforeClassRan); afterClassRan = beforeClassRan = false; System.setProperty(group1Property, "true"); checkResult(JUnitCore.runClasses(Nested1.class), 1, 1, 0); Assert.assertFalse(afterClassRan); Assert.assertFalse(beforeClassRan); afterClassRan = beforeClassRan = false; System.setProperty(group2Property, "true"); checkResult(JUnitCore.runClasses(Nested1.class), 1, 0, 0); Assert.assertTrue(afterClassRan); Assert.assertTrue(beforeClassRan); afterClassRan = beforeClassRan = false; System.setProperty(group1Property, "false"); checkResult(JUnitCore.runClasses(Nested1.class), 1, 1, 0); Assert.assertFalse(afterClassRan); Assert.assertFalse(beforeClassRan); } finally { System.clearProperty(group1Property); System.clearProperty(group2Property); } } @Test public void groupsOnASubsetOfMethods() { String group1Property = getSysProperty(Group1.class); String group2Property = getSysProperty(Group2.class); try { afterClassRan = beforeClassRan = false; checkResult(JUnitCore.runClasses(Nested3.class), 2, 1, 0); Assert.assertTrue(afterClassRan); Assert.assertTrue(beforeClassRan); afterClassRan = beforeClassRan = false; System.setProperty(group1Property, "true"); checkResult(JUnitCore.runClasses(Nested3.class), 2, 1, 0); Assert.assertTrue(afterClassRan); Assert.assertTrue(beforeClassRan); afterClassRan = beforeClassRan = false; System.setProperty(group2Property, "true"); checkResult(JUnitCore.runClasses(Nested3.class), 2, 0, 0); Assert.assertTrue(afterClassRan); Assert.assertTrue(beforeClassRan); afterClassRan = beforeClassRan = false; System.setProperty(group1Property, "false"); checkResult(JUnitCore.runClasses(Nested3.class), 2, 1, 0); Assert.assertTrue(afterClassRan); Assert.assertTrue(beforeClassRan); } finally { System.clearProperty(group1Property); System.clearProperty(group2Property); } } @Test public void groupsOnClass() { String group1Property = getSysProperty(Group1.class); String group2Property = getSysProperty(Group2.class); try { afterClassRan = beforeClassRan = false; checkResult(JUnitCore.runClasses(Nested2.class), 1, 1, 0); Assert.assertFalse(afterClassRan); Assert.assertFalse(beforeClassRan); afterClassRan = beforeClassRan = false; System.setProperty(group1Property, "true"); checkResult(JUnitCore.runClasses(Nested2.class), 1, 1, 0); Assert.assertFalse(afterClassRan); Assert.assertFalse(beforeClassRan); afterClassRan = beforeClassRan = false; System.setProperty(group2Property, "true"); checkResult(JUnitCore.runClasses(Nested2.class), 1, 0, 0); Assert.assertTrue(afterClassRan); Assert.assertTrue(beforeClassRan); afterClassRan = beforeClassRan = false; System.setProperty(group1Property, "false"); checkResult(JUnitCore.runClasses(Nested2.class), 1, 1, 0); Assert.assertFalse(afterClassRan); Assert.assertFalse(beforeClassRan); } finally { System.clearProperty(group1Property); System.clearProperty(group2Property); } } private void checkResult(Result result, int run, int ignored, int failures) { Assertions.assertThat(result.getRunCount()).as("run count").isEqualTo(run); Assertions.assertThat(result.getIgnoreCount()).as("ignore count").isEqualTo(ignored); Assertions.assertThat(result.getFailureCount()).as("failure count").isEqualTo(failures); } } TestThreadNameContainsTestName.java000066400000000000000000000013671235451432000426140ustar00rootroot00000000000000randomizedtesting-release-2.1.6/randomized-runner/src/test/java/com/carrotsearch/randomizedtestingpackage com.carrotsearch.randomizedtesting; import org.junit.Test; import com.carrotsearch.randomizedtesting.annotations.Timeout; /** * Test {@link Test#expected()}. */ public class TestThreadNameContainsTestName extends RandomizedTest { @Test public void testMarkerABC() { String tName = Thread.currentThread().getName(); assertTrue(tName, tName.contains("testMarkerABC")); } @Test @Timeout(millis = 0) public void testMarkerXYZ() { String tName = Thread.currentThread().getName(); assertTrue(tName, tName.contains("testMarkerXYZ")); } @Test @Timeout(millis = 1000) public void testMarkerKJI() { String tName = Thread.currentThread().getName(); assertTrue(tName, tName.contains("testMarkerKJI")); } } TestUncaughtExceptionsDuplicated.java000066400000000000000000000062231235451432000432570ustar00rootroot00000000000000randomizedtesting-release-2.1.6/randomized-runner/src/test/java/com/carrotsearch/randomizedtestingpackage com.carrotsearch.randomizedtesting; import java.util.*; import java.util.regex.Matcher; import java.util.regex.Pattern; import junit.framework.Assert; import org.junit.*; import org.junit.runner.JUnitCore; import org.junit.runner.Result; import org.junit.runner.notification.Failure; public class TestUncaughtExceptionsDuplicated extends WithNestedTestClass { public static class Nested1 extends RandomizedTest { @BeforeClass public static void beforeClass() throws Exception { assumeRunningNested(); Thread t = new Thread() { public void run() { throw new RuntimeException("foobar"); } }; t.start(); t.join(); } @Test public void test() {} } public static class Nested2 extends RandomizedTest { @BeforeClass public static void beforeClass() { assumeRunningNested(); } @Test public void test1() throws Exception { Thread t = new Thread() { public void run() { throw new RuntimeException("foobar1"); } }; t.start(); t.join(); } @Test public void test2() throws Exception { Thread t = new Thread() { public void run() { throw new RuntimeException("foobar2"); } }; t.start(); t.join(); } @Test public void test3() throws Exception { Thread t = new Thread() { public void run() { throw new RuntimeException("foobar3"); } }; t.start(); t.join(); } } public static class Nested3 extends RandomizedTest { @Before public void runBeforeTest() throws Exception { assumeRunningNested(); Thread t = new Thread() { public void run() { throw new RuntimeException("foobar"); } }; t.start(); t.join(); } @Test public void test1() throws Exception { } } @Test public void testExceptionInBeforeClassFailsTheTest() { Result runClasses = JUnitCore.runClasses(Nested1.class); Assert.assertEquals(1, runClasses.getFailureCount()); Assert.assertEquals(1, runClasses.getRunCount()); Assert.assertTrue(runClasses.getFailures().get(0).getTrace().contains("foobar")); } @Test public void testExceptionWithinTestFailsTheTest() { Result runClasses = JUnitCore.runClasses(Nested2.class); Assert.assertEquals(3, runClasses.getFailureCount()); Assert.assertEquals(3, runClasses.getRunCount()); ArrayList foobars = new ArrayList(); for (Failure f : runClasses.getFailures()) { Matcher m = Pattern.compile("foobar[0-9]+").matcher(f.getTrace()); while (m.find()) { foobars.add(m.group()); } } Collections.sort(foobars); Assert.assertEquals("[foobar1, foobar2, foobar3]", Arrays.toString(foobars.toArray())); } @Test public void testExceptionWithinBeforeFailsTheTest() { Result runClasses = JUnitCore.runClasses(Nested3.class); Assert.assertEquals(1, runClasses.getFailureCount()); Assert.assertEquals(1, runClasses.getRunCount()); Assert.assertTrue(runClasses.getFailures().get(0).getTrace().contains("foobar")); } } TestValidation.java000066400000000000000000000033721235451432000375340ustar00rootroot00000000000000randomizedtesting-release-2.1.6/randomized-runner/src/test/java/com/carrotsearch/randomizedtestingpackage com.carrotsearch.randomizedtesting; import java.util.Arrays; import org.junit.After; import org.junit.AfterClass; import org.junit.Assert; import org.junit.Before; import org.junit.BeforeClass; import org.junit.Test; public class TestValidation extends WithNestedTestClass { public class SuiteClassNotStatic { } static class SuiteClassNotPublic { } public static class BeforeClassNotStatic { @BeforeClass public void beforeClass() { } } public static class BeforeClassWithArgs { @BeforeClass public static void beforeClass(int a) { } } public static class AfterClassNotStatic { @AfterClass public void afterClass() { } } public static class AfterClassWithArgs { @AfterClass public static void afterClass(int a) { } } public static class BeforeStatic { @Before public static void before() { } } public static class BeforeWithArgs { @Before public void before(int a) { } } public static class AfterStatic { @After public static void after() { } } public static class AfterWithArgs { @After public void after(int a) { } } @SuppressWarnings({"unchecked"}) @Test public void checkBeforeClass() throws Exception { for (Class c : Arrays.asList( SuiteClassNotPublic.class, SuiteClassNotStatic.class, BeforeClassNotStatic.class, BeforeClassWithArgs.class, AfterClassNotStatic.class, AfterClassWithArgs.class, BeforeStatic.class, BeforeWithArgs.class, AfterStatic.class, AfterWithArgs.class)) { try { new RandomizedRunner(c); Assert.fail("Expected validation failure on: " + c.getName()); } catch (Exception e) { // Ok, expected. } } } } Utils.java000066400000000000000000000053161235451432000357020ustar00rootroot00000000000000randomizedtesting-release-2.1.6/randomized-runner/src/test/java/com/carrotsearch/randomizedtestingpackage com.carrotsearch.randomizedtesting; import java.util.Set; import java.util.logging.Logger; import org.fest.assertions.api.Assertions; import org.junit.Assert; import org.junit.runner.Result; import org.junit.runner.notification.Failure; public class Utils { /** * Assert a result has at least one failure with message. */ public static void assertFailureWithMessage(Result r, String message) { for (Failure f : r.getFailures()) { if (f.getTrace().contains(message)) { return; } } StringBuilder b = new StringBuilder("No failure with message: '" + message + "' (" + r.getFailures().size() + " failures):"); for (Failure f : r.getFailures()) { b.append("\n\t- ").append(f.getTrace()); } Logger.getLogger("").severe(b.toString()); Assert.fail(b.toString()); } public static void assertNoFailureWithMessage(Result r, String message) { boolean hadMessage = false; for (Failure f : r.getFailures()) { if (f.getTrace().contains(message)) { hadMessage = true; } } if (!hadMessage) return; StringBuilder b = new StringBuilder("Failure with message: '" + message + "' (" + r.getFailures().size() + " failures):"); for (Failure f : r.getFailures()) { b.append("\n\t- ").append(f.getTrace()); } Logger.getLogger("").severe(b.toString()); Assert.fail(b.toString()); } /** * Check that all thrown failures have been augmented and contain * a synthetic seed frame. */ public static void assertFailuresContainSeeds(Result r) { for (Failure f : r.getFailures()) { String seed = RandomizedRunner.seedFromThrowable(f.getException()); Assert.assertTrue("Not augmented: " + f.getTrace(), seed != null); } } /** * Package scope test access to {@link RandomizedContext#getRunnerSeed()}. */ public static long getRunnerSeed() { return RandomizedContext.current().getRunnerSeed(); } /** * Package scope test access to {@link Randomness#getSeed()}. */ public static long getSeed(Randomness randomness) { return randomness.getSeed(); } /** * Assert no threads with the given substring are present. */ public static void assertNoLiveThreadsContaining(String substring) { for (Thread t : getAllThreads()) { if (t.isAlive()) { Assertions.assertThat(t.getName()) .as("Unexpected live thread").doesNotContain(substring); } } } /** * Expose to non-package scope. */ public static Set getAllThreads() { return Threads.getAllThreads(); } /** * Expose to non-package scope. */ public static ThreadGroup getTopThreadGroup() { return Threads.getTopThreadGroup(); } } WithNestedTestClass.java000066400000000000000000000160661235451432000405120ustar00rootroot00000000000000randomizedtesting-release-2.1.6/randomized-runner/src/test/java/com/carrotsearch/randomizedtestingpackage com.carrotsearch.randomizedtesting; import java.io.IOException; import java.io.PrintStream; import java.io.StringWriter; import java.util.Arrays; import java.util.HashSet; import java.util.List; import java.util.concurrent.CountDownLatch; import java.util.logging.Handler; import java.util.logging.LogRecord; import java.util.logging.Logger; import java.util.logging.SimpleFormatter; import org.apache.commons.io.output.TeeOutputStream; import org.apache.commons.io.output.WriterOutputStream; import org.junit.After; import org.junit.AfterClass; import org.junit.Assume; import org.junit.Before; import org.junit.BeforeClass; import org.junit.ClassRule; import org.junit.Rule; import org.junit.Test; import org.junit.rules.RuleChain; import org.junit.rules.TestRule; import org.junit.runner.Description; import org.junit.runners.model.Statement; import com.carrotsearch.randomizedtesting.rules.StatementAdapter; import com.carrotsearch.randomizedtesting.rules.SystemPropertiesInvariantRule; import com.carrotsearch.randomizedtesting.rules.TestRuleAdapter; import com.google.common.collect.Lists; /** * Utility class to surround nested {@link RandomizedRunner} test suites. */ public class WithNestedTestClass { private static boolean runningNested; public enum Place { CLASS_RULE, BEFORE_CLASS, CONSTRUCTOR, TEST_RULE, BEFORE, TEST, AFTER, AFTER_CLASS, } public static class ApplyAtPlace extends RandomizedTest { public static Place place; public static Runnable runnable; @ClassRule public static TestRule classRule = new TestRuleAdapter() { protected void before() throws Throwable { ApplyAtPlace.apply(Place.CLASS_RULE); } }; @BeforeClass public static void beforeClass() { apply(Place.BEFORE_CLASS); } public ApplyAtPlace() { apply(Place.CONSTRUCTOR); } @Rule public TestRule testRule = new TestRuleAdapter() { protected void before() throws Throwable { ApplyAtPlace.apply(Place.TEST_RULE); } }; @Before public void before() { apply(Place.BEFORE); } @Test public void testMethod() { apply(Place.TEST); } @After public void after() { apply(Place.AFTER); } @AfterClass public static void afterClass() { apply(Place.AFTER_CLASS); } private static void apply(Place p) { if (place == p) { assumeRunningNested(); runnable.run(); } } } static { TestRule dumpLoggerOutputOnFailure = new TestRule() { @Override public Statement apply(Statement base, final Description description) { return new StatementAdapter(base) { protected void afterAlways(java.util.List errors) throws Throwable { if (!errors.isEmpty()) { sysout.println("-- " + description); sysout.println(loggingMessages); } } }; } }; SystemPropertiesInvariantRule noLeftOverProperties = new SystemPropertiesInvariantRule(new HashSet(Arrays.asList( "user.timezone"))); ruleChain = RuleChain .outerRule(noLeftOverProperties) .around(dumpLoggerOutputOnFailure); } @Rule public final static TestRule ruleChain; /** For capturing sysout. */ protected static PrintStream sysout; /** For capturing syserr. */ protected static PrintStream syserr; /** * Captured sysout/ syserr. */ private static StringWriter sw; /** * Captured java logging messages. */ private static StringWriter loggingMessages; /** * Master logger. */ private static Logger logger; /** * Previous handlers attached to the master. */ private static Handler[] handlers; /** * Zombie threads. */ private static List zombies = Lists.newArrayList(); private static volatile Object zombieToken; @BeforeClass public static final void setupNested() throws IOException { runningNested = true; zombieToken = new Object(); // capture sysout/ syserr. sw = new StringWriter(); sysout = System.out; syserr = System.err; System.setOut(new PrintStream(new TeeOutputStream(System.out, new WriterOutputStream(sw)))); System.setErr(new PrintStream(new TeeOutputStream(System.err, new WriterOutputStream(sw)))); // Add custom logging handler because java logging keeps a reference to previous System.err. loggingMessages = new StringWriter(); logger = Logger.getLogger(""); handlers = logger.getHandlers(); for (Handler h : handlers) logger.removeHandler(h); logger.addHandler(new Handler() { final SimpleFormatter formatter = new SimpleFormatter(); @Override public void publish(LogRecord record) { loggingMessages.write(formatter.format(record) + "\n"); } @Override public void flush() {} @Override public void close() throws SecurityException {} }); } @AfterClass public static final void clearNested() throws Exception { zombieToken = null; runningNested = false; ApplyAtPlace.runnable = null; ApplyAtPlace.place = null; System.setOut(sysout); System.setErr(syserr); for (Handler h : logger.getHandlers()) logger.removeHandler(h); for (Handler h : handlers) logger.addHandler(h); for (Thread t : zombies) { t.interrupt(); } for (Thread t : zombies) { t.join(); } } @After public void after() { // Reset zombie thread marker. RandomizedRunner.zombieMarker.set(false); } @Before public void before() { sw.getBuffer().setLength(0); loggingMessages.getBuffer().setLength(0); } protected static String getSysouts() { System.out.flush(); System.err.flush(); return sw.toString(); } public static String getLoggingMessages() { return loggingMessages.toString(); } protected static boolean isRunningNested() { return runningNested; } protected static void assumeRunningNested() { Assume.assumeTrue(runningNested); } protected static Thread startZombieThread(String name) { final CountDownLatch latch = new CountDownLatch(1); Thread t = new Thread(name) { private final Object token = zombieToken; public void run() { latch.countDown(); while (zombieToken == token) { try { Thread.sleep(1000); } catch (InterruptedException e) { // ignore. } } } }; t.start(); zombies.add(t); try { latch.await(); } catch (InterruptedException e) { throw new RuntimeException(e); } return t; } protected static Thread startThread(String name) { final CountDownLatch latch = new CountDownLatch(1); Thread t = new Thread(name) { public void run() { latch.countDown(); sleepForever(); } private void sleepForever() { while (true) RandomizedTest.sleep(1000); } }; t.start(); try { latch.await(); } catch (InterruptedException e) { throw new RuntimeException(e); } return t; } } 000077500000000000000000000000001235451432000357325ustar00rootroot00000000000000randomizedtesting-release-2.1.6/randomized-runner/src/test/java/com/carrotsearch/randomizedtesting/contractsTestAnnotationInheritance.java000066400000000000000000000054371235451432000437320ustar00rootroot00000000000000randomizedtesting-release-2.1.6/randomized-runner/src/test/java/com/carrotsearch/randomizedtesting/contractspackage com.carrotsearch.randomizedtesting.contracts; import java.util.List; import org.fest.assertions.api.Assertions; import org.junit.After; import org.junit.AfterClass; import org.junit.Before; import org.junit.BeforeClass; import org.junit.Rule; import org.junit.Test; import org.junit.rules.TestRule; import org.junit.runner.Description; import org.junit.runner.JUnitCore; import org.junit.runner.Request; import org.junit.runners.model.Statement; import com.carrotsearch.randomizedtesting.RandomizedRunner; import com.carrotsearch.randomizedtesting.WithNestedTestClass; import com.google.common.base.Joiner; import com.google.common.collect.Lists; /** * Verify if annotations are inherited. */ public class TestAnnotationInheritance extends WithNestedTestClass { final static List order = Lists.newArrayList(); public static class Nested1 { @Rule public TestRule rules = new TestRule() { @Override public Statement apply(final Statement base, Description description) { return new Statement() { public void evaluate() throws Throwable { order.add("rule-before"); base.evaluate(); order.add("rule-after"); } }; } }; @BeforeClass public static void beforeClass() { order.add("before-class"); } @Before public void before() { order.add("before-test"); } @Test public void testMethod1() { order.add("testMethod1"); } @After public void after() { order.add("after-test"); } @AfterClass public static void afterClass() { order.add("after-class"); } } public static class Nested2 extends Nested1 { public static void beforeClass() { order.add("shadowed-before-class"); } @Override public void before() { order.add("inherited before-test"); } @Override public void after() { order.add("inherited after-test"); } @Override public void testMethod1() { order.add("inherited testMethod"); } public static void afterClass() { order.add("shadowed-after-class"); } } @Test public void checkOldMethodRules() throws Exception { assertSameExecution(Nested2.class); } private void assertSameExecution(Class clazz) throws Exception { order.clear(); JUnitCore.runClasses(clazz); List order1 = Lists.newArrayList(order); order.clear(); new JUnitCore().run(Request.runner(new RandomizedRunner(clazz))); List order2 = Lists.newArrayList(order); order.clear(); String msg = "# JUnit order:\n" + Joiner.on("\n").join(order1) + "\n" + "# RR order:\n" + Joiner.on("\n").join(order2); Assertions.assertThat(order2).as(msg).isEqualTo(order1); } } TestAssumptionsAtClassLevel.java000066400000000000000000000041131235451432000442240ustar00rootroot00000000000000randomizedtesting-release-2.1.6/randomized-runner/src/test/java/com/carrotsearch/randomizedtesting/contractspackage com.carrotsearch.randomizedtesting.contracts; import static org.junit.Assert.assertEquals; import java.util.ArrayList; import java.util.Arrays; import java.util.List; import org.junit.After; import org.junit.AfterClass; import org.junit.Assume; import org.junit.Before; import org.junit.BeforeClass; import org.junit.Test; import org.junit.runner.JUnitCore; import org.junit.runner.Result; import com.carrotsearch.randomizedtesting.RandomizedTest; import com.carrotsearch.randomizedtesting.WithNestedTestClass; /** * Check assumptions at suite level (in {@link BeforeClass}). */ public class TestAssumptionsAtClassLevel extends WithNestedTestClass { static final List callOrder = new ArrayList(); /** * Test superclass. */ public static class Super extends RandomizedTest { @BeforeClass public static void beforeClassSuper() { callOrder.add("beforeClassSuper"); assumeRunningNested(); Assume.assumeTrue(false); } @AfterClass public static void afterClassSuper() { callOrder.add("afterClassSuper"); } } /** * Test subclass. */ public static class SubSub extends Super { @BeforeClass public static void beforeClass() { callOrder.add("beforeClassSub"); } @Before public void beforeTestSub() { callOrder.add("beforeTestSub"); } @Test public void testMethod() { callOrder.add("testMethodSub"); } @After public void afterTestSub() { callOrder.add("afterTestSub"); } @AfterClass public static void afterClass() { callOrder.add("afterClassSub"); } } @Before public void cleanup() { callOrder.clear(); } @Test public void checkOrder() { Result result = JUnitCore.runClasses(SubSub.class); assertEquals(0, result.getRunCount()); assertEquals(1, result.getIgnoreCount()); assertEquals(0, result.getFailureCount()); List expected = Arrays.asList( "beforeClassSuper", "afterClassSub", "afterClassSuper" ); assertEquals(expected, callOrder); } } TestBeforeAfterMethodOrder.java000066400000000000000000000137341235451432000437660ustar00rootroot00000000000000randomizedtesting-release-2.1.6/randomized-runner/src/test/java/com/carrotsearch/randomizedtesting/contractspackage com.carrotsearch.randomizedtesting.contracts; import static org.junit.Assert.assertEquals; import java.util.ArrayList; import java.util.List; import java.util.Locale; import org.junit.After; import org.junit.AfterClass; import org.junit.Assert; import org.junit.Before; import org.junit.BeforeClass; import org.junit.Rule; import org.junit.Test; import org.junit.rules.MethodRule; import org.junit.rules.RuleChain; import org.junit.rules.TestRule; import org.junit.runner.Description; import org.junit.runner.JUnitCore; import org.junit.runner.Result; import org.junit.runners.model.FrameworkMethod; import org.junit.runners.model.Statement; import com.carrotsearch.randomizedtesting.RandomizedContext; import com.carrotsearch.randomizedtesting.RandomizedRunner; import com.carrotsearch.randomizedtesting.WithNestedTestClass; import com.carrotsearch.randomizedtesting.annotations.Repeat; import com.carrotsearch.randomizedtesting.annotations.Seed; /** * Hooks ordering with respect to class hierarchies. */ @SuppressWarnings("deprecation") public class TestBeforeAfterMethodOrder extends WithNestedTestClass { static final List callOrder = new ArrayList(); public static class AppendMethodRule implements MethodRule { private String text; public AppendMethodRule(String text) { this.text = text; } @Override public Statement apply(final Statement base, FrameworkMethod method, Object target) { return new Statement() { @Override public void evaluate() throws Throwable { callOrder.add(text + "-before"); base.evaluate(); callOrder.add(text + "-after"); } }; } } public static class AppendRule implements TestRule { private String text; public AppendRule(String text) { this.text = text; } @Override public Statement apply(final Statement base, Description description) { return new Statement() { @Override public void evaluate() throws Throwable { callOrder.add(text + "-before"); base.evaluate(); callOrder.add(text + "-after"); } }; } } /** * Test superclass. */ public static class Super { @BeforeClass public static void beforeClassSuper() { callOrder.add("beforeClassSuper"); } @Rule public TestRule superRule = RuleChain .outerRule(new AppendRule("superOuterTestRule")) .around(new AppendRule("superMiddleTestRule")) .around(new AppendRule("superInnerTestRule")); @Rule public MethodRule superMethodRule = new AppendMethodRule("superMethodRule"); @Before public final void beforeTest() { callOrder.add("beforeTestSuper"); } protected void testMethod() { throw new RuntimeException("Should be overridden and public."); } @After public final void afterTest() { callOrder.add("afterTestSuper"); } @AfterClass public static void afterClassSuper() { callOrder.add("afterClassSuper"); } } /** * Test subclass. */ public static class SubSub extends Super { @Rule public TestRule rule = RuleChain .outerRule(new AppendRule(" subOuterTestRule")) .around(new AppendRule(" subMiddleTestRule")) .around(new AppendRule(" subInnerTestRule")); @Rule public MethodRule methodRule = new AppendMethodRule(" subMethodRule"); @BeforeClass public static void beforeClass() { callOrder.add(" beforeClassSub"); } @Before public void beforeTestSub() { callOrder.add(" beforeTestSub"); } @Test public void testMethod() { callOrder.add(" testMethodSub"); } @After public void afterTestSub() { callOrder.add(" afterTestSub"); } @AfterClass public static void afterClass() { callOrder.add(" afterClassSub"); } } /** * Test subclass. */ @Seed("deadbeef") public static class SubSubFixedSeed extends Super { @BeforeClass public static void beforeClass() { callOrder.add("beforeClassSubFS"); } @Before public void beforeTestSub() { assumeRunningNested(); callOrder.add("beforeTestSubFS"); } @Test @Repeat(iterations = 10) public void testMethod1() { callOrder.add("testMethodSubFS1 " + RandomizedContext.current().getRandom().nextInt()); } @Test @Repeat(iterations = 10) public void testMethod2() { callOrder.add("testMethodSubFS2 " + RandomizedContext.current().getRandom().nextInt()); } @After public void afterTestSub() { callOrder.add("afterTestSubFS"); } @AfterClass public static void afterClass() { callOrder.add("afterClassSubFS"); } } @Before public void cleanup() { callOrder.clear(); } @Test public void checkOrder() throws Exception { // Normal JUnit. Result result = JUnitCore.runClasses(SubSub.class); assertEquals(1, result.getRunCount()); // Save order. ArrayList junitOrder = new ArrayList(callOrder); callOrder.clear(); new JUnitCore().run(new RandomizedRunner(SubSub.class)); if (!callOrder.equals(junitOrder)) { final int i = junitOrder.size(); final int j = callOrder.size(); System.out.println(String.format(Locale.ENGLISH, "%-30s | %-30s", "JUnit4", "RR")); for (int k = 0; k < Math.max(i, j); k++) { System.out.println(String.format(Locale.ENGLISH, "%-30s | %-30s", k < i ? junitOrder.get(k) : "--", k < j ? callOrder.get(k) : "--")); } Assert.fail("JUnit4 and RandomizedRunner differed."); } } @Test public void checkOrderFixedSeed() throws Exception { new JUnitCore().run(new RandomizedRunner(SubSubFixedSeed.class)); ArrayList order = new ArrayList(callOrder); callOrder.clear(); new JUnitCore().run(new RandomizedRunner(SubSubFixedSeed.class)); assertEquals(order, callOrder); } } TestClassLevelIgnore.java000066400000000000000000000013411235451432000426350ustar00rootroot00000000000000randomizedtesting-release-2.1.6/randomized-runner/src/test/java/com/carrotsearch/randomizedtesting/contractspackage com.carrotsearch.randomizedtesting.contracts; import org.junit.*; import org.junit.runner.JUnitCore; import org.junit.runner.Result; import com.carrotsearch.randomizedtesting.RandomizedTest; import com.carrotsearch.randomizedtesting.WithNestedTestClass; /** * Class-level {@link Ignore}. */ public class TestClassLevelIgnore extends WithNestedTestClass { @Ignore public static class Nested extends RandomizedTest { @Test public void ignored() { } } @Test public void allIgnored() { Result result = JUnitCore.runClasses(Nested.class); Assert.assertEquals(0, result.getRunCount()); Assert.assertEquals(0, result.getFailureCount()); Assert.assertEquals(1, result.getIgnoreCount()); } } TestClassRules.java000066400000000000000000000036731235451432000415260ustar00rootroot00000000000000randomizedtesting-release-2.1.6/randomized-runner/src/test/java/com/carrotsearch/randomizedtesting/contractspackage com.carrotsearch.randomizedtesting.contracts; import java.util.List; import org.junit.AfterClass; import org.junit.Assert; import org.junit.BeforeClass; import org.junit.ClassRule; import org.junit.Test; import org.junit.rules.RuleChain; import org.junit.rules.TestRule; import org.junit.runner.Description; import org.junit.runner.JUnitCore; import org.junit.runner.Request; import org.junit.runners.model.Statement; import com.carrotsearch.randomizedtesting.RandomizedRunner; import com.carrotsearch.randomizedtesting.WithNestedTestClass; import com.google.common.collect.Lists; /** * {@link ClassRule} support. */ public class TestClassRules extends WithNestedTestClass { final static List order = Lists.newArrayList(); public static class ClassRuleSupport { @ClassRule public static TestRule rules = RuleChain.outerRule(new TestRule() { @Override public Statement apply(final Statement base, Description description) { return new Statement() { public void evaluate() throws Throwable { order.add("rule-before"); base.evaluate(); order.add("rule-after"); } }; } }); @BeforeClass public static void beforeClass() { order.add("before-class"); } @AfterClass public static void afterClass() { order.add("after-class"); } @Test public void passing() { order.add("passing"); } } @Test public void checkOldMethodRules() throws Exception { assertSameExecution(ClassRuleSupport.class); } private void assertSameExecution(Class clazz) throws Exception { order.clear(); JUnitCore.runClasses(clazz); List order1 = Lists.newArrayList(order); order.clear(); new JUnitCore().run(Request.runner(new RandomizedRunner(clazz))); List order2 = Lists.newArrayList(order); order.clear(); Assert.assertEquals(order1, order2); } } 000077500000000000000000000000001235451432000361035ustar00rootroot00000000000000randomizedtesting-release-2.1.6/randomized-runner/src/test/java/com/carrotsearch/randomizedtesting/generatorsStringGeneratorTestBase.java000066400000000000000000000042721235451432000435230ustar00rootroot00000000000000randomizedtesting-release-2.1.6/randomized-runner/src/test/java/com/carrotsearch/randomizedtesting/generatorspackage com.carrotsearch.randomizedtesting.generators; import org.junit.Test; import com.carrotsearch.randomizedtesting.RandomizedTest; import com.carrotsearch.randomizedtesting.annotations.Repeat; /** * Base class for testing {@link StringGenerator}s. */ public abstract class StringGeneratorTestBase extends RandomizedTest { protected final StringGenerator generator; protected StringGeneratorTestBase(StringGenerator generator) { this.generator = generator; } @Test @Repeat(iterations = 10) public void checkFixedCodePointLength() { int codepoints = iterationFix(randomIntBetween(1, 100)); String s = generator.ofCodePointsLength(getRandom(), codepoints, codepoints); assertEquals(s, codepoints, s.codePointCount(0, s.length())); } @Test @Repeat(iterations = 10) public void checkRandomCodePointLength() { int from = iterationFix(randomIntBetween(1, 100)); int to = from + randomInt(100); String s = generator.ofCodePointsLength(getRandom(), from, to); int codepoints = s.codePointCount(0, s.length()); assertTrue(codepoints + " not within " + from + "-" + to, from <= codepoints && codepoints <= to); } @Test @Repeat(iterations = 10) public void checkFixedCodeUnitLength() { int codeunits = iterationFix(randomIntBetween(1, 100)); String s = generator.ofCodeUnitsLength(getRandom(), codeunits, codeunits); assertEquals(s, codeunits, s.length()); assertEquals(s, codeunits, s.toCharArray().length); } @Test @Repeat(iterations = 10) public void checkRandomCodeUnitLength() { int from = iterationFix(randomIntBetween(1, 100)); int to = from + randomInt(100); String s = generator.ofCodeUnitsLength(getRandom(), from, to); int codeunits = s.length(); assertTrue(codeunits + " not within " + from + "-" + to, from <= codeunits && codeunits <= to); } @Test public void checkZeroLength() { assertEquals("", generator.ofCodePointsLength(getRandom(), 0, 0)); assertEquals("", generator.ofCodeUnitsLength(getRandom(), 0, 0)); } /** * Correct the count if a given generator doesn't support all possible values (in tests). */ protected int iterationFix(int i) { return i; } } TestCodepointSetGenerator.java000066400000000000000000000035531235451432000440630ustar00rootroot00000000000000randomizedtesting-release-2.1.6/randomized-runner/src/test/java/com/carrotsearch/randomizedtesting/generatorspackage com.carrotsearch.randomizedtesting.generators; import org.junit.Test; import org.junit.runner.RunWith; import org.junit.runners.Suite; import org.junit.runners.Suite.SuiteClasses; @RunWith(Suite.class) @SuiteClasses({ TestCodepointSetGenerator.CodepointSetOnChars.class, TestCodepointSetGenerator.CodepointSetOnCodePoints.class, TestCodepointSetGenerator.CodepointSetOnSurrogatesOnly.class }) public class TestCodepointSetGenerator { private final static int [] codepoints = { 'a', 'b', 'c', 'd', 0xd7ff, 0xffff, 0x10000, 0x1D11E, 0x10FFFD, }; private final static int [] surrogates = { 0x10000, 0x1D11E, 0x10FFFD, }; private final static String withSurrogates = new String(codepoints, 0, codepoints.length); public static class CodepointSetOnChars extends StringGeneratorTestBase { public CodepointSetOnChars() { super(new CodepointSetGenerator(new char[] { 'a', 'b', 'c', 'd', 0x100, 0xd7ff, 0xffff })); } @Test(expected = IllegalArgumentException.class) public void testSurrogatesInConstructor() { new CodepointSetGenerator(withSurrogates.toCharArray()); } } public static class CodepointSetOnCodePoints extends StringGeneratorTestBase { public CodepointSetOnCodePoints() { super(new CodepointSetGenerator(withSurrogates)); } } public static class CodepointSetOnSurrogatesOnly extends StringGeneratorTestBase { public CodepointSetOnSurrogatesOnly() { super(new CodepointSetGenerator(new String(surrogates, 0, surrogates.length))); } @Test(expected = IllegalArgumentException.class) public void testOddCodePoints() { generator.ofCodeUnitsLength(getRandom(), 3, 3); } @Override protected int iterationFix(int i) { return i & ~1; // Even only. } } } TestRandomPicks.java000066400000000000000000000016671235451432000420320ustar00rootroot00000000000000randomizedtesting-release-2.1.6/randomized-runner/src/test/java/com/carrotsearch/randomizedtesting/generatorspackage com.carrotsearch.randomizedtesting.generators; import java.util.ArrayList; import java.util.Arrays; import java.util.HashSet; import org.junit.Test; import com.carrotsearch.randomizedtesting.RandomizedTest; public class TestRandomPicks extends RandomizedTest { @Test(expected = IllegalArgumentException.class) public void testRandomFromEmptyCollection() { RandomPicks.randomFrom(getRandom(), new HashSet()); } @Test public void testRandomFromCollection() { Object t = new Object(); Object r = RandomPicks.randomFrom(getRandom(), new HashSet(Arrays.asList(t))); assertSame(r, t); } @Test(expected = IllegalArgumentException.class) public void testRandomFromList() { RandomPicks.randomFrom(getRandom(), new ArrayList()); } @Test(expected = IllegalArgumentException.class) public void testRandomFromArray() { RandomPicks.randomFrom(getRandom(), new Object[] {}); } } TestRealisticUnicodeGenerator.java000066400000000000000000000003311235451432000447000ustar00rootroot00000000000000randomizedtesting-release-2.1.6/randomized-runner/src/test/java/com/carrotsearch/randomizedtesting/generatorspackage com.carrotsearch.randomizedtesting.generators; public class TestRealisticUnicodeGenerator extends StringGeneratorTestBase { public TestRealisticUnicodeGenerator() { super(new UnicodeGenerator()); } } TestUnicodeGenerator.java000066400000000000000000000003071235451432000430430ustar00rootroot00000000000000randomizedtesting-release-2.1.6/randomized-runner/src/test/java/com/carrotsearch/randomizedtesting/generatorspackage com.carrotsearch.randomizedtesting.generators; public class TestUnicodeGenerator extends StringGeneratorTestBase { public TestUnicodeGenerator() { super(new UnicodeGenerator()); } } 000077500000000000000000000000001235451432000362235ustar00rootroot00000000000000randomizedtesting-release-2.1.6/randomized-runner/src/test/java/com/carrotsearch/randomizedtesting/inheritanceJUnitAnnotationPropagation.java000066400000000000000000000077061235451432000443700ustar00rootroot00000000000000randomizedtesting-release-2.1.6/randomized-runner/src/test/java/com/carrotsearch/randomizedtesting/inheritancepackage com.carrotsearch.randomizedtesting.inheritance; import java.util.Collections; import java.util.List; import org.fest.assertions.api.Assertions; import org.junit.Before; import org.junit.BeforeClass; import org.junit.Ignore; import org.junit.Rule; import org.junit.Test; import org.junit.rules.TestRule; import org.junit.runner.Description; import org.junit.runner.JUnitCore; import org.junit.runner.Request; import org.junit.runners.model.Statement; import com.carrotsearch.randomizedtesting.RandomizedRunner; import com.google.common.base.Joiner; import com.google.common.collect.Lists; public class JUnitAnnotationPropagation { final static List order = Lists.newArrayList(); public static class Super { @Rule public TestRule rules = new TestRule() { @Override public Statement apply(final Statement base, Description description) { return new Statement() { public void evaluate() throws Throwable { order.add("rule-before"); base.evaluate(); order.add("rule-after"); } }; } }; @BeforeClass public static void beforeClass1() { order.add("super.beforeclass1"); } public static void beforeClass2() { order.add("super.beforeclass2"); } @BeforeClass public static void beforeClass3() { order.add("super.beforeclass3"); } @Before public void before1() { order.add("super.before1"); } public void before2() { order.add("super.before2"); } @Before public void before3() { order.add("super.before3"); } @Test public void testMethod1() { order.add("super.testMethod1"); } public void testMethod2() { order.add("super.testMethod2"); } @Test public void testMethod3() { order.add("super.testMethod3"); } // Awkward cases of annotations and virtual methods. @Ignore public void testMethod4() { order.add("super.testMethod4"); } @Test public void testMethod5() { order.add("super.testMethod5"); } } public static class Sub extends Super { public static void beforeClass1() { order.add("sub.beforeclass1"); } @BeforeClass public static void beforeClass2() { order.add("sub.beforeclass2"); } @BeforeClass public static void beforeClass3() { order.add("sub.beforeclass3"); } public void before1() { order.add("sub.before1"); } @Before public void before2() { order.add("sub.before2"); } @Before public void before3() { order.add("sub.before3"); } public void testMethod1() { order.add("sub.testMethod1"); } @Test public void testMethod2() { order.add("sub.testMethod2"); } @Test public void testMethod3() { order.add("sub.testMethod3"); } @Test public void testMethod4() { order.add("sub.testMethod4"); } @Ignore public void testMethod5() { order.add("sub.testMethod5"); } } @Test public void checkOldMethodRules() throws Exception { assertSameExecution(Sub.class); } private void assertSameExecution(Class clazz) throws Exception { order.clear(); JUnitCore.runClasses(clazz); List order1 = Lists.newArrayList(order); order.clear(); new JUnitCore().run(Request.runner(new RandomizedRunner(clazz))); List order2 = Lists.newArrayList(order); order.clear(); String msg = "# JUnit order:\n" + Joiner.on("\n").join(order1) + "\n" + "# RR order:\n" + Joiner.on("\n").join(order2); // Don't care about relative ordering of hook methods. Assertions.assertThat(noNumbers(order2)).as(msg).isEqualTo(noNumbers(order1)); // But do care that all methods show up. Collections.sort(order1); Collections.sort(order2); Assertions.assertThat(order2).as(msg).isEqualTo(order1); } private List noNumbers(List in) { List out = Lists.newArrayList(); for (String s : in) { out.add(s.replaceAll("[0-9]+$", "")); } return out; } } PrivateHooksPropagation.java000066400000000000000000000037641235451432000437220ustar00rootroot00000000000000randomizedtesting-release-2.1.6/randomized-runner/src/test/java/com/carrotsearch/randomizedtesting/inheritancepackage com.carrotsearch.randomizedtesting.inheritance; import java.util.List; import org.fest.assertions.api.Assertions; import org.junit.Before; import org.junit.BeforeClass; import org.junit.Test; import org.junit.runner.JUnitCore; import org.junit.runner.Request; import com.carrotsearch.randomizedtesting.RandomizedRunner; import com.carrotsearch.randomizedtesting.RandomizedTest; import com.google.common.base.Joiner; import com.google.common.collect.Lists; public class PrivateHooksPropagation { final static List order = Lists.newArrayList(); public static class Super extends RandomizedTest { @BeforeClass private static void beforeClass1() { order.add("super.beforeclass1"); } @BeforeClass protected static void beforeClass2() { order.add("super.beforeclass2"); } @Before private void before1() { order.add("super.before1"); } @Before protected void before2() { order.add("super.before2"); } @Test public void testMethod1() { order.add("super.testMethod1"); } } public static class Sub extends Super { @BeforeClass private static void beforeClass1() { order.add("sub.beforeclass1"); } @BeforeClass protected static void beforeClass2() { order.add("sub.beforeclass2"); } @Before private void before1() { order.add("sub.before1"); } @Before protected void before2() { order.add("sub.before2"); } } @Test public void checkOldMethodRules() throws Exception { assertSameExecution(Sub.class); } private void assertSameExecution(Class clazz) throws Exception { new JUnitCore().run(Request.runner(new RandomizedRunner(clazz))); List order1 = Lists.newArrayList(order); order.clear(); String msg = "# RR order:\n" + Joiner.on("\n").join(order1); Assertions.assertThat(order1).as(msg).containsOnly( "super.beforeclass1", "sub.beforeclass1", "sub.beforeclass2", "super.before1", "sub.before1", "sub.before2", "super.testMethod1"); } } 000077500000000000000000000000001235451432000350645ustar00rootroot00000000000000randomizedtesting-release-2.1.6/randomized-runner/src/test/java/com/carrotsearch/randomizedtesting/rulesTestNoClassHooksShadowingRule.java000066400000000000000000000044771235451432000436450ustar00rootroot00000000000000randomizedtesting-release-2.1.6/randomized-runner/src/test/java/com/carrotsearch/randomizedtesting/rulespackage com.carrotsearch.randomizedtesting.rules; import org.fest.assertions.api.Assertions; import org.junit.BeforeClass; import org.junit.ClassRule; import org.junit.Test; import org.junit.rules.RuleChain; import org.junit.rules.TestRule; import org.junit.runner.Description; import org.junit.runner.JUnitCore; import org.junit.runner.Result; import org.junit.runners.model.Statement; import com.carrotsearch.randomizedtesting.RandomizedTest; import com.carrotsearch.randomizedtesting.WithNestedTestClass; public class TestNoClassHooksShadowingRule extends WithNestedTestClass { public static class Super extends RandomizedTest { private static TestRule assumeNotNestedRule = new TestRule() { public Statement apply(final Statement base, Description description) { return new Statement() { public void evaluate() throws Throwable { assumeRunningNested(); base.evaluate(); } }; } }; @ClassRule public static TestRule classRules = RuleChain .outerRule(assumeNotNestedRule) .around(new NoClassHooksShadowingRule()); @BeforeClass public static void before() {} @BeforeClass private static void privateBefore() {} @Test public void testEmpty() {} } public static class Sub1 extends Super { public static void before() {} } public static class Sub2 extends Super { @BeforeClass public static void before() {} } public static class Sub3 extends Super { @BeforeClass private static void privateBefore() {} } @Test public void testShadowingNoAnnotation() { Result runClasses = JUnitCore.runClasses(Sub1.class); Assertions.assertThat(runClasses.getFailures()).isNotEmpty(); Assertions.assertThat(runClasses.getFailures().get(0).getTrace()) .contains("shadow or override each other"); } @Test public void testShadowingWithAnnotation() { Result runClasses = JUnitCore.runClasses(Sub2.class); Assertions.assertThat(runClasses.getFailures()).isNotEmpty(); Assertions.assertThat(runClasses.getFailures().get(0).getTrace()) .contains("shadow or override each other"); } @Test public void testIndependentChains() { Result runClasses = JUnitCore.runClasses(Sub3.class); Assertions.assertThat(runClasses.getFailures()).isEmpty(); } } TestNoInstanceHooksOverridesRule.java000066400000000000000000000053511235451432000443530ustar00rootroot00000000000000randomizedtesting-release-2.1.6/randomized-runner/src/test/java/com/carrotsearch/randomizedtesting/rulespackage com.carrotsearch.randomizedtesting.rules; import java.lang.reflect.Method; import org.fest.assertions.api.Assertions; import org.junit.Before; import org.junit.ClassRule; import org.junit.Test; import org.junit.rules.RuleChain; import org.junit.rules.TestRule; import org.junit.runner.Description; import org.junit.runner.JUnitCore; import org.junit.runner.Result; import org.junit.runners.model.Statement; import com.carrotsearch.randomizedtesting.RandomizedTest; import com.carrotsearch.randomizedtesting.WithNestedTestClass; public class TestNoInstanceHooksOverridesRule extends WithNestedTestClass { public static class Super extends RandomizedTest { private static TestRule assumeNotNestedRule = new TestRule() { public Statement apply(final Statement base, Description description) { return new Statement() { public void evaluate() throws Throwable { assumeRunningNested(); base.evaluate(); } }; } }; @ClassRule public static TestRule classRules = RuleChain .outerRule(assumeNotNestedRule) .around(new NoInstanceHooksOverridesRule() { @Override protected boolean verify(Method key) { return !key.getName().equals("setup"); } }); @Before public void before() {} @Before private void privateBefore() {} @Before public void setup() {} @Test public void testEmpty() {} } public static class Sub1 extends Super { public void before() {} } public static class Sub2 extends Super { @Before public void before() {} } public static class Sub3 extends Super { @Before private void privateBefore() {} } public static class Sub4 extends Super { @Override public void setup() {} } @Test public void testOverrideNoAnnotation() { Result runClasses = JUnitCore.runClasses(Sub1.class); Assertions.assertThat(runClasses.getFailures()).isNotEmpty(); Assertions.assertThat(runClasses.getFailures().get(0).getTrace()) .contains("shadow or override each other"); } @Test public void testOverrideWithAnnotation() { Result runClasses = JUnitCore.runClasses(Sub2.class); Assertions.assertThat(runClasses.getFailures()).isNotEmpty(); Assertions.assertThat(runClasses.getFailures().get(0).getTrace()) .contains("shadow or override each other"); } @Test public void testIndependentChains() { Result runClasses = JUnitCore.runClasses(Sub3.class); Assertions.assertThat(runClasses.getFailures()).isEmpty(); } @Test public void testFiltering() { Result runClasses = JUnitCore.runClasses(Sub4.class); Assertions.assertThat(runClasses.getFailures()).isEmpty(); } } TestStaticFieldsInvariantRule.java000066400000000000000000000061531235451432000436560ustar00rootroot00000000000000randomizedtesting-release-2.1.6/randomized-runner/src/test/java/com/carrotsearch/randomizedtesting/rulespackage com.carrotsearch.randomizedtesting.rules; import java.util.HashMap; import java.util.Map; import org.fest.assertions.api.Assertions; import org.junit.BeforeClass; import org.junit.ClassRule; import org.junit.Test; import org.junit.rules.RuleChain; import org.junit.rules.TestRule; import org.junit.runner.Description; import org.junit.runner.JUnitCore; import org.junit.runner.Result; import org.junit.runners.model.Statement; import com.carrotsearch.randomizedtesting.RandomizedTest; import com.carrotsearch.randomizedtesting.WithNestedTestClass; import com.carrotsearch.randomizedtesting.annotations.ThreadLeakScope; import com.carrotsearch.randomizedtesting.annotations.ThreadLeakScope.Scope; public class TestStaticFieldsInvariantRule extends WithNestedTestClass { static int LEAK_THRESHOLD = 5 * 1024 * 1024; @ThreadLeakScope(Scope.SUITE) public static class Base extends RandomizedTest { private static TestRule assumeNotNestedRule = new TestRule() { public Statement apply(final Statement base, Description description) { return new Statement() { public void evaluate() throws Throwable { assumeRunningNested(); base.evaluate(); } }; } }; @ClassRule public static TestRule classRules = RuleChain .outerRule(assumeNotNestedRule) .around(new StaticFieldsInvariantRule(LEAK_THRESHOLD, true)); @Test public void testEmpty() {} } public static class Smaller extends Base { static byte [] field0; @BeforeClass private static void setup() { field0 = new byte [LEAK_THRESHOLD / 2]; } } public static class Exceeding extends Smaller { static byte [] field1; static byte [] field2; static int [] field3; static long field4; final static long [] field5 = new long [1024]; @BeforeClass private static void setup() { field1 = new byte [LEAK_THRESHOLD / 2]; field2 = new byte [100]; field3 = new int [100]; } } public static class MultipleReferences extends Base { static Object ref1, ref2, ref3, ref4, ref5, ref6; static Object ref7 = null; static { Map map = new HashMap(); map.put("key", new byte [1024 * 1024 * 2]); ref1 = ref2 = ref3 = ref4 = ref5 = ref6 = map; } } @Test public void testReferencesCountedMultipleTimes() { Result runClasses = JUnitCore.runClasses(MultipleReferences.class); Assertions.assertThat(runClasses.getFailures()).isEmpty(); } @Test public void testPassingUnderThreshold() { Result runClasses = JUnitCore.runClasses(Smaller.class); Assertions.assertThat(runClasses.getFailures()).isEmpty(); } @Test public void testFailingAboveThreshold() { Result runClasses = JUnitCore.runClasses(Exceeding.class); Assertions.assertThat(runClasses.getFailures()).hasSize(1); Assertions.assertThat(runClasses.getFailures().get(0).getTrace()) .contains(".field0") .contains(".field1") .contains(".field2") .contains(".field3") .doesNotContain(".field5"); } } TestSystemPropertiesInvariantRule.java000066400000000000000000000075651235451432000446510ustar00rootroot00000000000000randomizedtesting-release-2.1.6/randomized-runner/src/test/java/com/carrotsearch/randomizedtesting/rulespackage com.carrotsearch.randomizedtesting.rules; import java.util.Properties; import org.junit.AfterClass; import org.junit.Assert; import org.junit.BeforeClass; import org.junit.ClassRule; import org.junit.Rule; import org.junit.Test; import org.junit.rules.RuleChain; import org.junit.rules.TestRule; import org.junit.runner.*; import org.junit.runner.notification.Failure; import org.junit.runners.model.Statement; import com.carrotsearch.randomizedtesting.WithNestedTestClass; public class TestSystemPropertiesInvariantRule extends WithNestedTestClass { public static final String PROP_KEY1 = "new-property-1"; public static final String VALUE1 = "new-value-1"; public static class Base { private static TestRule assumeNotNestedRule = new TestRule() { public Statement apply(final Statement base, Description description) { return new Statement() { public void evaluate() throws Throwable { assumeRunningNested(); base.evaluate(); } }; } }; @ClassRule public static TestRule classRules = RuleChain.outerRule(assumeNotNestedRule).around(new SystemPropertiesInvariantRule()); @Rule public TestRule testRules = RuleChain.outerRule(new SystemPropertiesInvariantRule()); @Test public void testEmpty() {} } public static class InBeforeClass extends Base { @BeforeClass public static void beforeClass() { System.setProperty(PROP_KEY1, VALUE1); } } public static class InAfterClass extends Base { @AfterClass public static void afterClass() { System.setProperty(PROP_KEY1, VALUE1); } } public static class InTestMethod extends Base { @Test public void testMethod1() { if (System.getProperty(PROP_KEY1) != null) { throw new RuntimeException("Shouldn't be here."); } System.setProperty(PROP_KEY1, VALUE1); } @Test public void testMethod2() { testMethod1(); } } public static class NonStringProperties extends Base { @Test public void testMethod1() { if (System.getProperties().get(PROP_KEY1) != null) { throw new RuntimeException("Will pass."); } Properties properties = System.getProperties(); properties.put(PROP_KEY1, new Object()); Assert.assertTrue(System.getProperties().get(PROP_KEY1) != null); } @Test public void testMethod2() { testMethod1(); } @AfterClass public static void cleanup() { System.getProperties().remove(PROP_KEY1); } } @Test public void testRuleInvariantBeforeClass() { Result runClasses = JUnitCore.runClasses(InBeforeClass.class); Assert.assertEquals(1, runClasses.getFailureCount()); Assert.assertTrue(runClasses.getFailures().get(0).getMessage() .contains(PROP_KEY1)); Assert.assertNull(System.getProperty(PROP_KEY1)); } @Test public void testRuleInvariantAfterClass() { Result runClasses = JUnitCore.runClasses(InAfterClass.class); Assert.assertEquals(1, runClasses.getFailureCount()); Assert.assertTrue(runClasses.getFailures().get(0).getMessage() .contains(PROP_KEY1)); Assert.assertNull(System.getProperty(PROP_KEY1)); } @Test public void testRuleInvariantInTestMethod() { Result runClasses = JUnitCore.runClasses(InTestMethod.class); Assert.assertEquals(2, runClasses.getFailureCount()); for (Failure f : runClasses.getFailures()) { Assert.assertTrue(f.getMessage().contains(PROP_KEY1)); } Assert.assertNull(System.getProperty(PROP_KEY1)); } @Test public void testNonStringProperties() { Result runClasses = JUnitCore.runClasses(NonStringProperties.class); Assert.assertEquals(1, runClasses.getFailureCount()); Assert.assertTrue(runClasses.getFailures().get(0).getMessage().contains("Will pass")); Assert.assertEquals(3, runClasses.getRunCount()); } } 000077500000000000000000000000001235451432000355775ustar00rootroot00000000000000randomizedtesting-release-2.1.6/randomized-runner/src/test/java/com/carrotsearch/randomizedtesting/snippetsTheGoodBadAndUglySnippet.java000066400000000000000000000033641235451432000432370ustar00rootroot00000000000000randomizedtesting-release-2.1.6/randomized-runner/src/test/java/com/carrotsearch/randomizedtesting/snippetspackage com.carrotsearch.randomizedtesting.snippets; import org.junit.BeforeClass; import org.junit.Test; import com.carrotsearch.randomizedtesting.WithNestedTestClass; import com.carrotsearch.randomizedtesting.annotations.Repeat; import com.carrotsearch.randomizedtesting.annotations.ThreadLeakAction; import com.carrotsearch.randomizedtesting.annotations.ThreadLeakAction.Action; import com.carrotsearch.randomizedtesting.annotations.ThreadLeakLingering; import com.carrotsearch.randomizedtesting.annotations.ThreadLeakScope; import com.carrotsearch.randomizedtesting.annotations.ThreadLeakScope.Scope; public class TheGoodBadAndUglySnippet extends WithNestedTestClass { /** * This is cheating so that snippets appear to be extending RandomizedTest * but at the same time snippety tests won't execute in Eclipse. */ public static class RandomizedTest extends com.carrotsearch.randomizedtesting.RandomizedTest { @BeforeClass public static void runAsTest() { assumeRunningNested(); } } // [[[start:goodbadugly]]] @ThreadLeakScope(Scope.TEST) @ThreadLeakAction({Action.WARN, Action.INTERRUPT}) @ThreadLeakLingering(linger = 1000) public static class TheGoodBadAndUgly extends RandomizedTest { @Test public void good() { // I do nothing and I'm good. } @Test @Repeat(iterations = 10) public void bad() { // I fail randomly, about 20% of the time. assertFalse(randomIntBetween(1, 100) <= 20); } @Test public void ugly() { // I start and abandon a thread which falls // outside the test's scope. The test will fail. new Thread() { public void run() { RandomizedTest.sleep(5000); } }.start(); } } // [[[end:goodbadugly]]] }000077500000000000000000000000001235451432000356035ustar00rootroot00000000000000randomizedtesting-release-2.1.6/randomized-runner/src/test/java/com/carrotsearch/randomizedtesting/timeoutsTest001TimeoutSuite.java000066400000000000000000000033341235451432000421720ustar00rootroot00000000000000randomizedtesting-release-2.1.6/randomized-runner/src/test/java/com/carrotsearch/randomizedtesting/timeoutspackage com.carrotsearch.randomizedtesting.timeouts; import org.fest.assertions.api.Assertions; import org.junit.Test; import org.junit.runner.JUnitCore; import org.junit.runner.Result; import com.carrotsearch.randomizedtesting.RandomizedTest; import com.carrotsearch.randomizedtesting.Utils; import com.carrotsearch.randomizedtesting.WithNestedTestClass; import com.carrotsearch.randomizedtesting.annotations.Timeout; import com.carrotsearch.randomizedtesting.annotations.TimeoutSuite; public class Test001TimeoutSuite extends WithNestedTestClass { /** * Nested test suite class with {@link TimeoutSuite}. */ @TimeoutSuite(millis = 500) @Timeout(millis = 5000) public static class Nested extends ApplyAtPlace {} @Test public void testClassRule() { check(Place.CLASS_RULE); } @Test public void testBeforeClass() { check(Place.BEFORE_CLASS); } @Test public void testConstructor() { check(Place.CONSTRUCTOR); } @Test public void testTestRule() { check(Place.TEST_RULE); } @Test public void testBefore() { check(Place.BEFORE); } @Test public void testTest() { check(Place.TEST); } @Test public void testAfter() { check(Place.AFTER); } @Test public void testAfterClass() { check(Place.AFTER_CLASS); } /** * Check a given timeout place. */ private void check(Place p) { ApplyAtPlace.place = p; ApplyAtPlace.runnable = new Runnable() { @Override public void run() { while (true) RandomizedTest.sleep(10000); } }; Result r = JUnitCore.runClasses(Nested.class); Utils.assertFailureWithMessage(r, "Suite timeout exceeded"); Utils.assertFailuresContainSeeds(r); Assertions.assertThat(getLoggingMessages()) .doesNotContain("Test execution timed out"); } } Test002TimeoutMethod.java000066400000000000000000000022271235451432000423220ustar00rootroot00000000000000randomizedtesting-release-2.1.6/randomized-runner/src/test/java/com/carrotsearch/randomizedtesting/timeoutspackage com.carrotsearch.randomizedtesting.timeouts; import org.junit.Test; import org.junit.runner.JUnitCore; import org.junit.runner.Result; import com.carrotsearch.randomizedtesting.RandomizedTest; import com.carrotsearch.randomizedtesting.Utils; import com.carrotsearch.randomizedtesting.WithNestedTestClass; import com.carrotsearch.randomizedtesting.annotations.Timeout; public class Test002TimeoutMethod extends WithNestedTestClass { @Timeout(millis = 25) public static class Nested extends ApplyAtPlace {} @Test public void testTestRule() { check(Place.TEST_RULE); } @Test public void testBefore() { check(Place.BEFORE); } @Test public void testTest() { check(Place.TEST); } @Test public void testAfter() { check(Place.AFTER); } /** * Check a given timeout place. */ private void check(Place p) { ApplyAtPlace.place = p; ApplyAtPlace.runnable = new Runnable() { @Override public void run() { while (true) RandomizedTest.sleep(1000); } }; Result r = JUnitCore.runClasses(Nested.class); Utils.assertFailureWithMessage(r, "Test timeout exceeded"); Utils.assertFailuresContainSeeds(r); } } Test003ThreadLeaksMethod.java000066400000000000000000000044351235451432000430670ustar00rootroot00000000000000randomizedtesting-release-2.1.6/randomized-runner/src/test/java/com/carrotsearch/randomizedtesting/timeoutspackage com.carrotsearch.randomizedtesting.timeouts; import org.fest.assertions.api.Assertions; import org.junit.Assert; import org.junit.Test; import org.junit.runner.JUnitCore; import org.junit.runner.Result; import com.carrotsearch.randomizedtesting.LifecycleScope; import com.carrotsearch.randomizedtesting.Utils; import com.carrotsearch.randomizedtesting.WithNestedTestClass; import com.carrotsearch.randomizedtesting.annotations.ThreadLeakAction; import com.carrotsearch.randomizedtesting.annotations.ThreadLeakAction.Action; import com.carrotsearch.randomizedtesting.annotations.ThreadLeakLingering; import com.carrotsearch.randomizedtesting.annotations.ThreadLeakScope; import com.carrotsearch.randomizedtesting.annotations.ThreadLeakScope.Scope; public class Test003ThreadLeaksMethod extends WithNestedTestClass { @ThreadLeakScope(Scope.TEST) @ThreadLeakLingering(linger = 0) @ThreadLeakAction({Action.WARN, Action.INTERRUPT}) public static class Nested extends ApplyAtPlace {} @Test public void testClassRule() { suiteLeak(Place.CLASS_RULE); } @Test public void testBeforeClass() { suiteLeak(Place.BEFORE_CLASS); } @Test public void testConstructor() { suiteLeak(Place.CONSTRUCTOR); } @Test public void testTestRule() { testLeak(Place.TEST_RULE); } @Test public void testBefore() { testLeak(Place.BEFORE); } @Test public void testTest() { testLeak(Place.TEST); } @Test public void testAfter() { testLeak(Place.AFTER); } @Test public void testAfterClass() { suiteLeak(Place.AFTER_CLASS); } private void testLeak(Place p) { check(p, LifecycleScope.TEST); } private void suiteLeak(Place p) { check(p, LifecycleScope.SUITE); } /** * Check a given timeout place. */ private void check(Place p, LifecycleScope scope) { ApplyAtPlace.place = p; ApplyAtPlace.runnable = new Runnable() { @Override public void run() { startThread("foobar"); } }; Result r = JUnitCore.runClasses(Nested.class); Utils.assertFailureWithMessage(r, "1 thread leaked from " + scope.toString() + " scope at"); Assert.assertEquals(1, r.getFailureCount()); Utils.assertFailuresContainSeeds(r); Utils.assertNoLiveThreadsContaining("foobar"); Assertions.assertThat(getLoggingMessages()) .doesNotContain("Uncaught exception"); } } Test004ThreadLeaksSuite.java000066400000000000000000000040621235451432000427350ustar00rootroot00000000000000randomizedtesting-release-2.1.6/randomized-runner/src/test/java/com/carrotsearch/randomizedtesting/timeoutspackage com.carrotsearch.randomizedtesting.timeouts; import org.fest.assertions.api.Assertions; import org.junit.Assert; import org.junit.Test; import org.junit.runner.JUnitCore; import org.junit.runner.Result; import com.carrotsearch.randomizedtesting.Utils; import com.carrotsearch.randomizedtesting.WithNestedTestClass; import com.carrotsearch.randomizedtesting.annotations.ThreadLeakAction; import com.carrotsearch.randomizedtesting.annotations.ThreadLeakAction.Action; import com.carrotsearch.randomizedtesting.annotations.ThreadLeakScope.Scope; import com.carrotsearch.randomizedtesting.annotations.ThreadLeakLingering; import com.carrotsearch.randomizedtesting.annotations.ThreadLeakScope; public class Test004ThreadLeaksSuite extends WithNestedTestClass { @ThreadLeakScope(Scope.SUITE) @ThreadLeakLingering(linger = 0) @ThreadLeakAction({Action.WARN, Action.INTERRUPT}) public static class Nested extends ApplyAtPlace {} @Test public void testClassRule() { suiteLeak(Place.CLASS_RULE); } @Test public void testBeforeClass() { suiteLeak(Place.BEFORE_CLASS); } @Test public void testConstructor() { suiteLeak(Place.CONSTRUCTOR); } @Test public void testTestRule() { suiteLeak(Place.TEST_RULE); } @Test public void testBefore() { suiteLeak(Place.BEFORE); } @Test public void testTest() { suiteLeak(Place.TEST); } @Test public void testAfter() { suiteLeak(Place.AFTER); } @Test public void testAfterClass() { suiteLeak(Place.AFTER_CLASS); } /** * Check a given timeout place. */ private void suiteLeak(Place p) { ApplyAtPlace.place = p; ApplyAtPlace.runnable = new Runnable() { @Override public void run() { startThread("foobar"); } }; Result r = JUnitCore.runClasses(Nested.class); Utils.assertFailureWithMessage(r, "1 thread leaked from SUITE scope at"); Assert.assertEquals(1, r.getFailureCount()); Utils.assertFailuresContainSeeds(r); Utils.assertNoLiveThreadsContaining("foobar"); Assertions.assertThat(getLoggingMessages()) .doesNotContain("Uncaught exception"); } } Test005ThreadLeaksSystemThreads.java000066400000000000000000000037551235451432000444540ustar00rootroot00000000000000randomizedtesting-release-2.1.6/randomized-runner/src/test/java/com/carrotsearch/randomizedtesting/timeoutspackage com.carrotsearch.randomizedtesting.timeouts; import java.lang.reflect.Method; import java.security.MessageDigest; import java.security.NoSuchAlgorithmException; import java.util.logging.Level; import java.util.logging.Logger; import org.fest.assertions.api.Assertions; import org.junit.Test; import org.junit.runner.JUnitCore; import org.junit.runner.Result; import com.carrotsearch.randomizedtesting.RandomizedTest; import com.carrotsearch.randomizedtesting.WithNestedTestClass; import com.carrotsearch.randomizedtesting.annotations.ThreadLeakGroup; import com.carrotsearch.randomizedtesting.annotations.ThreadLeakGroup.Group; /** * Checks if known demon threads spawned by certain library methods are properly * handled. */ public class Test005ThreadLeaksSystemThreads extends WithNestedTestClass { @ThreadLeakGroup(Group.MAIN) public static class Nested extends RandomizedTest { @Test public void tokenPoller() throws Exception { assumeRunningNested(); try { MessageDigest instance = MessageDigest.getInstance("MD5"); instance.update(randomByte()); instance.digest(); } catch (NoSuchAlgorithmException e) { Logger.getAnonymousLogger().log(Level.SEVERE, "No MD5 in MessageDigest?", e); } } @Test public void gcDaemon() throws Exception { assumeRunningNested(); try { Class clazz = Class.forName("sun.misc.GC"); Method method = clazz.getDeclaredMethod("requestLatency", new Class[] {long.class}); method.invoke(null, Long.valueOf(3600000)); } catch (ClassNotFoundException e) { // Ignore, must be running under a JVM without this class. } } } @Test public void leftOverThread() throws Throwable { Result r = JUnitCore.runClasses(Nested.class); Assertions.assertThat(r.getFailures()).isEmpty(); Assertions.assertThat(getLoggingMessages()) .doesNotContain("java.lang.Thread.sleep") .doesNotContain("Uncaught exception"); } } Test006TimeoutAndThreadLeak.java000066400000000000000000000033261235451432000435360ustar00rootroot00000000000000randomizedtesting-release-2.1.6/randomized-runner/src/test/java/com/carrotsearch/randomizedtesting/timeoutspackage com.carrotsearch.randomizedtesting.timeouts; import org.fest.assertions.api.Assertions; import org.junit.Test; import org.junit.runner.JUnitCore; import org.junit.runner.Result; import com.carrotsearch.randomizedtesting.RandomizedTest; import com.carrotsearch.randomizedtesting.Utils; import com.carrotsearch.randomizedtesting.WithNestedTestClass; import com.carrotsearch.randomizedtesting.annotations.TimeoutSuite; public class Test006TimeoutAndThreadLeak extends WithNestedTestClass { /** * Nested test suite class with {@link TimeoutSuite}. */ @TimeoutSuite(millis = 500) public static class Nested extends ApplyAtPlace {} @Test public void testClassRule() { check(Place.CLASS_RULE); } @Test public void testBeforeClass() { check(Place.BEFORE_CLASS); } @Test public void testConstructor() { check(Place.CONSTRUCTOR); } @Test public void testTestRule() { check(Place.TEST_RULE); } @Test public void testBefore() { check(Place.BEFORE); } @Test public void testTest() { check(Place.TEST); } @Test public void testAfter() { check(Place.AFTER); } @Test public void testAfterClass() { check(Place.AFTER_CLASS); } /** * Check a given timeout place. */ private void check(Place p) { ApplyAtPlace.place = p; ApplyAtPlace.runnable = new Runnable() { @Override public void run() { startThread("foobar"); while (true) RandomizedTest.sleep(1000); } }; Result r = JUnitCore.runClasses(Nested.class); Utils.assertFailureWithMessage(r, "Suite timeout exceeded"); Utils.assertFailuresContainSeeds(r); Utils.assertNoLiveThreadsContaining("foobar"); Assertions.assertThat(getLoggingMessages()) .doesNotContain("Uncaught exception"); } } Test007UncaughtExceptions.java000066400000000000000000000032221235451432000433540ustar00rootroot00000000000000randomizedtesting-release-2.1.6/randomized-runner/src/test/java/com/carrotsearch/randomizedtesting/timeoutspackage com.carrotsearch.randomizedtesting.timeouts; import org.fest.assertions.api.Assertions; import org.junit.Test; import org.junit.runner.JUnitCore; import org.junit.runner.Result; import com.carrotsearch.randomizedtesting.RandomizedTest; import com.carrotsearch.randomizedtesting.Utils; import com.carrotsearch.randomizedtesting.WithNestedTestClass; public class Test007UncaughtExceptions extends WithNestedTestClass { static ThreadGroup parentGroup; public static class Nested extends RandomizedTest { @Test public void checkGlobal() throws Exception { assumeRunningNested(); final Thread t = new Thread(parentGroup, "XYZ") { public void run() { throw new RuntimeException("Yoda died."); } }; t.start(); t.join(); } } @Test public void testUncaughtExceptionsAtMainGroup() throws Exception { ThreadGroup parentTg = Thread.currentThread().getThreadGroup(); while (parentTg.getParent() != null) parentTg = parentTg.getParent(); parentGroup = parentTg; check(); } @Test public void testUncaughtExceptionsAtThreadGroup() throws Exception { parentGroup = null; check(); } /** * Apply assertions. */ private void check() throws Exception { Result r = JUnitCore.runClasses(Nested.class); Utils.assertFailureWithMessage(r, "Captured an uncaught exception in thread: "); Utils.assertFailureWithMessage(r, "Yoda died."); Utils.assertFailuresContainSeeds(r); Utils.assertNoLiveThreadsContaining("XYZ"); Assertions.assertThat(getLoggingMessages()) .contains("Uncaught exception") .contains("Yoda died."); } } Test008SeedsAnnotation.java000066400000000000000000000035661235451432000426460ustar00rootroot00000000000000randomizedtesting-release-2.1.6/randomized-runner/src/test/java/com/carrotsearch/randomizedtesting/timeoutspackage com.carrotsearch.randomizedtesting.timeouts; import java.util.ArrayList; import java.util.HashMap; import junit.framework.Assert; import org.fest.assertions.api.Assertions; import org.junit.Test; import org.junit.runner.JUnitCore; import org.junit.runner.Result; import com.carrotsearch.randomizedtesting.RandomizedTest; import com.carrotsearch.randomizedtesting.Utils; import com.carrotsearch.randomizedtesting.WithNestedTestClass; import com.carrotsearch.randomizedtesting.annotations.*; import static org.fest.assertions.data.MapEntry.*; /** * Check {@link Seeds}. */ public class Test008SeedsAnnotation extends WithNestedTestClass { final static ArrayList seeds = new ArrayList(); public static class Nested extends RandomizedTest { @Seeds({ @Seed("deadbeef"), @Seed("cafebabe"), @Seed // Adds a randomized execution too. }) @Test @Repeat(iterations = 2, useConstantSeed = true) public void testMe() { assumeRunningNested(); seeds.add(Long.toHexString(Utils.getSeed(getContext().getRandomness()))); } } @Test public void checkSeeds() { HashMap counts = new HashMap(); int N = 4; for (int i = 0; i < N; i++) { seeds.clear(); Result result = JUnitCore.runClasses(Nested.class); Assert.assertEquals(3 * 2, result.getRunCount()); Assertions.assertThat(result.getFailures()).isEmpty(); for (String s : seeds) { if (!counts.containsKey(s)) counts.put(s, 1L); else counts.put(s, counts.get(s) + 1); } } Assertions.assertThat(counts).contains(entry("deadbeef", N * 2L)); Assertions.assertThat(counts).contains(entry("cafebabe", N * 2L)); counts.remove("deadbeef"); counts.remove("cafebabe"); // Allow for a single collision. Assert.assertTrue(counts.size() >= N - 1); } } Test009TimeoutOrNotIdenticalSequence.java000066400000000000000000000040271235451432000454600ustar00rootroot00000000000000randomizedtesting-release-2.1.6/randomized-runner/src/test/java/com/carrotsearch/randomizedtesting/timeoutspackage com.carrotsearch.randomizedtesting.timeouts; import java.util.ArrayList; import java.util.List; import org.fest.assertions.api.Assertions; import org.junit.Test; import org.junit.runner.JUnitCore; import com.carrotsearch.randomizedtesting.RandomizedTest; import com.carrotsearch.randomizedtesting.WithNestedTestClass; import com.carrotsearch.randomizedtesting.annotations.Repeat; import com.carrotsearch.randomizedtesting.annotations.Seed; import com.carrotsearch.randomizedtesting.annotations.Timeout; import com.google.common.collect.Lists; /** * It should not matter for the random sequence whether {@link Timeout} is * used or not. */ public class Test009TimeoutOrNotIdenticalSequence extends WithNestedTestClass { final static ArrayList seeds = new ArrayList(); public static class Nested1 extends RandomizedTest { @Test @Seed("deadbeef") @Repeat(iterations = 2, useConstantSeed = false) public void testNoTimeout() { assumeRunningNested(); seeds.add(randomAsciiOfLength(20)); } } public static class Nested2 extends Nested1 { @Override @Test @Seed("deadbeef") @Repeat(iterations = 2, useConstantSeed = false) @Timeout(millis = 30 * 1000) public void testNoTimeout() { super.testNoTimeout(); } } @Timeout(millis = 30 * 1000) public static class Nested3 extends Nested1 { @Override @Test @Seed("deadbeef") @Repeat(iterations = 2, useConstantSeed = false) @Timeout(millis = 30 * 1000) public void testNoTimeout() { super.testNoTimeout(); } } @Test public void checkAllRunsIdentical() { List previous = null; for (Class c : new Class [] {Nested1.class, Nested2.class, Nested3.class}) { seeds.clear(); Assertions.assertThat(JUnitCore.runClasses(c).wasSuccessful()).isTrue(); if (previous != null) { Assertions.assertThat(seeds).as("Class " + c.getSimpleName()).isEqualTo(previous); } else { previous = Lists.newArrayList(seeds); } } } } Test010Zombies.java000066400000000000000000000060411235451432000411400ustar00rootroot00000000000000randomizedtesting-release-2.1.6/randomized-runner/src/test/java/com/carrotsearch/randomizedtesting/timeoutspackage com.carrotsearch.randomizedtesting.timeouts; import org.fest.assertions.api.Assertions; import org.junit.Rule; import org.junit.Test; import org.junit.runner.JUnitCore; import org.junit.runner.Result; import com.carrotsearch.randomizedtesting.SysGlobals; import com.carrotsearch.randomizedtesting.Utils; import com.carrotsearch.randomizedtesting.WithNestedTestClass; import com.carrotsearch.randomizedtesting.annotations.ThreadLeakAction; import com.carrotsearch.randomizedtesting.annotations.ThreadLeakAction.Action; import com.carrotsearch.randomizedtesting.annotations.ThreadLeakLingering; import com.carrotsearch.randomizedtesting.annotations.ThreadLeakScope; import com.carrotsearch.randomizedtesting.annotations.ThreadLeakScope.Scope; import com.carrotsearch.randomizedtesting.annotations.ThreadLeakZombies; import com.carrotsearch.randomizedtesting.annotations.ThreadLeakZombies.Consequence; import com.carrotsearch.randomizedtesting.rules.SystemPropertiesRestoreRule; public class Test010Zombies extends WithNestedTestClass { @ThreadLeakScope(Scope.TEST) @ThreadLeakLingering(linger = 0) @ThreadLeakAction({Action.INTERRUPT}) @ThreadLeakZombies(Consequence.IGNORE_REMAINING_TESTS) public static class Nested extends ApplyAtPlace {} @Test public void testClassRule() { check(Place.CLASS_RULE); } @Test public void testBeforeClass() { check(Place.BEFORE_CLASS); } @Test public void testConstructor() { check(Place.CONSTRUCTOR); } @Test public void testTestRule() { check(Place.TEST_RULE); } @Test public void testBefore() { check(Place.BEFORE); } @Test public void testTest() { check(Place.TEST); } @Test public void testAfter() { check(Place.AFTER); } @Test public void testAfterClass() { check(Place.AFTER_CLASS); } @Rule public SystemPropertiesRestoreRule restoreProperties = new SystemPropertiesRestoreRule(); /** * Start a zombie thread somewhere. Ensure all suites are ignored afterwards. */ private void check(Place p) { System.setProperty(SysGlobals.SYSPROP_KILLWAIT(), "10"); System.setProperty(SysGlobals.SYSPROP_KILLATTEMPTS(), "2"); ApplyAtPlace.place = p; ApplyAtPlace.runnable = new Runnable() { @Override public void run() { startZombieThread("foobarZombie"); } }; // Run a class spawning zombie threads. Result r = JUnitCore.runClasses(Nested.class); Utils.assertFailureWithMessage(r, "1 thread leaked"); Utils.assertFailureWithMessage(r, "foobarZombie"); Utils.assertFailuresContainSeeds(r); Assertions.assertThat(getLoggingMessages()) .contains("There are still zombie threads that couldn't be terminated:"); // Run another suite. Everything should be ignored because of zombie threads. for (Place p2 : Place.values()) { ApplyAtPlace.place = p2; ApplyAtPlace.runnable = new Runnable() { @Override public void run() { throw new RuntimeException(); } }; r = JUnitCore.runClasses(Nested.class); Assertions.assertThat(r.wasSuccessful()).as("At: " + p2).isTrue(); } } } Test011RunawayThreads.java000066400000000000000000000107541235451432000425000ustar00rootroot00000000000000randomizedtesting-release-2.1.6/randomized-runner/src/test/java/com/carrotsearch/randomizedtesting/timeoutspackage com.carrotsearch.randomizedtesting.timeouts; import java.util.concurrent.*; import org.junit.Assert; import org.junit.BeforeClass; import org.junit.Test; import org.junit.runner.*; import org.junit.runner.notification.Failure; import com.carrotsearch.randomizedtesting.RandomizedContext; import com.carrotsearch.randomizedtesting.RandomizedRunner; import com.carrotsearch.randomizedtesting.RandomizedTest; import com.carrotsearch.randomizedtesting.Utils; import com.carrotsearch.randomizedtesting.WithNestedTestClass; import com.carrotsearch.randomizedtesting.annotations.ThreadLeakLingering; @RunWith(RandomizedRunner.class) public class Test011RunawayThreads extends WithNestedTestClass { private abstract static class ThreadWithException extends Thread { public volatile Throwable throwable; @Override public final void run() { try { runWrapped(); } catch (Throwable t) { throwable = t; } } public final ThreadWithException startAndJoin() throws Throwable { this.start(); try { this.join(5000); if (throwable != null) throw throwable; } catch (InterruptedException e) { throw e; } return this; } protected abstract void runWrapped(); } @Test public void subThreadContextPropagation() throws Throwable { final long seed = Utils.getRunnerSeed(); new ThreadWithException() { protected void runWrapped() { RandomizedContext ctx = RandomizedContext.current(); Assert.assertEquals(seed, Utils.getSeed(ctx.getRandomness())); } }.startAndJoin(); } @ThreadLeakLingering(linger = 2000) @Test public void ExecutorServiceContextPropagation() throws Throwable { final long seed = Utils.getRunnerSeed(); final ExecutorService executor = Executors.newCachedThreadPool(); try { executor.submit(new Runnable() { public void run() { RandomizedContext ctx = RandomizedContext.current(); Assert.assertEquals(seed, Utils.getSeed(ctx.getRandomness())); } }).get(); } catch (ExecutionException e) { throw e.getCause(); } finally { executor.shutdown(); executor.awaitTermination(1, TimeUnit.SECONDS); } } public static class Nested extends RandomizedTest { final boolean withJoin; public Nested() { this(true); } protected Nested(boolean withJoin) { this.withJoin = withJoin; } @Test public void spinoffAndThrow() throws Exception{ assumeRunningNested(); Thread t = new Thread() { public void run() { RandomizedTest.sleep(500); throw new RuntimeException("spinoff exception"); } }; t.start(); if (withJoin) { t.join(); } } } public static class NestedNoJoin extends Nested { public NestedNoJoin() { super(false); } } @Test public void subUncaughtExceptionInSpunOffThread() throws Throwable { Result r = JUnitCore.runClasses(Nested.class); Assert.assertEquals(1, r.getFailureCount()); Failure testFailure = r.getFailures().get(0); Throwable testException = testFailure.getException(); Throwable threadException = testException.getCause(); Assert.assertNotNull(RandomizedRunner.seedFromThrowable(testException)); Assert.assertNotNull(RandomizedRunner.seedFromThrowable(threadException)); } @Test public void subNotJoined() throws Throwable { Result r = JUnitCore.runClasses(NestedNoJoin.class); Assert.assertEquals(1, r.getFailureCount()); Failure testFailure = r.getFailures().get(0); Throwable testException = testFailure.getException(); Assert.assertNotNull(RandomizedRunner.seedFromThrowable(testException)); } public static class NestedClassScope extends RandomizedTest { @BeforeClass public static void startThread() { if (!isRunningNested()) return; new Thread() { @Override public void run() { RandomizedTest.sleep(5000); } }.start(); } @Test public void spinoffAndThrow() throws Exception{ assumeRunningNested(); } } @Test public void subNotJoinOnClassLevel() throws Throwable { Result r = JUnitCore.runClasses(NestedClassScope.class); Assert.assertEquals(1, r.getFailureCount()); Failure testFailure = r.getFailures().get(0); Throwable testException = testFailure.getException(); Assert.assertNotNull(RandomizedRunner.seedFromThrowable(testException)); } } Test012RunawayThreadsKilledAtOnce.java000066400000000000000000000027371235451432000447220ustar00rootroot00000000000000randomizedtesting-release-2.1.6/randomized-runner/src/test/java/com/carrotsearch/randomizedtesting/timeoutspackage com.carrotsearch.randomizedtesting.timeouts; import java.util.concurrent.CountDownLatch; import org.junit.Assert; import org.junit.Test; import org.junit.runner.*; import com.carrotsearch.randomizedtesting.RandomizedRunner; import com.carrotsearch.randomizedtesting.WithNestedTestClass; @RunWith(RandomizedRunner.class) public class Test012RunawayThreadsKilledAtOnce extends WithNestedTestClass { @RunWith(RandomizedRunner.class) public static class NestedClass { @Test public void lotsOfStubbornThreads() throws Throwable { assumeRunningNested(); final CountDownLatch latch = new CountDownLatch(50); Thread [] threads = new Thread [(int) latch.getCount()]; for (int i = 0; i < threads.length; i++) { threads[i] = new Thread("stubborn-" + i) { @Override public void run() { latch.countDown(); try { Thread.sleep(20000); } catch (InterruptedException e) { // Ignore } } }; threads[i].start(); } // Wait for all threads to be really started. latch.await(); } } @Test public void testLotsOfStubbornThreads() { long start = System.currentTimeMillis(); Result result = JUnitCore.runClasses(NestedClass.class); long end = System.currentTimeMillis(); Assert.assertEquals(1, result.getFailureCount()); Assert.assertTrue((end - start) + " msec?", (end - start) < 1000 * 10); } } Test013ThreadLeaksScopeNone.java000066400000000000000000000027661235451432000435460ustar00rootroot00000000000000randomizedtesting-release-2.1.6/randomized-runner/src/test/java/com/carrotsearch/randomizedtesting/timeoutspackage com.carrotsearch.randomizedtesting.timeouts; import org.fest.assertions.api.Assertions; import org.junit.Assert; import org.junit.Test; import org.junit.runner.JUnitCore; import org.junit.runner.Result; import com.carrotsearch.randomizedtesting.WithNestedTestClass; import com.carrotsearch.randomizedtesting.annotations.ThreadLeakScope; import com.carrotsearch.randomizedtesting.annotations.ThreadLeakScope.Scope; public class Test013ThreadLeaksScopeNone extends WithNestedTestClass { @ThreadLeakScope(Scope.NONE) public static class Nested extends ApplyAtPlace {} @Test public void testClassRule() { testLeak(Place.CLASS_RULE); } @Test public void testBeforeClass() { testLeak(Place.BEFORE_CLASS); } @Test public void testConstructor() { testLeak(Place.CONSTRUCTOR); } @Test public void testTestRule() { testLeak(Place.TEST_RULE); } @Test public void testBefore() { testLeak(Place.BEFORE); } @Test public void testTest() { testLeak(Place.TEST); } @Test public void testAfter() { testLeak(Place.AFTER); } @Test public void testAfterClass() { testLeak(Place.AFTER_CLASS); } private void testLeak(Place p) { ApplyAtPlace.place = p; ApplyAtPlace.runnable = new Runnable() { @Override public void run() { startZombieThread("foobar"); } }; Result r = JUnitCore.runClasses(Nested.class); Assert.assertEquals(0, r.getFailureCount()); Assertions.assertThat(getLoggingMessages()).isEmpty(); Assertions.assertThat(getSysouts()).isEmpty(); } } Test014Timeout.java000066400000000000000000000017531235451432000411670ustar00rootroot00000000000000randomizedtesting-release-2.1.6/randomized-runner/src/test/java/com/carrotsearch/randomizedtesting/timeoutspackage com.carrotsearch.randomizedtesting.timeouts; import junit.framework.Assert; import org.junit.Test; import org.junit.runner.JUnitCore; import org.junit.runner.Result; import com.carrotsearch.randomizedtesting.RandomizedTest; import com.carrotsearch.randomizedtesting.WithNestedTestClass; /** * Test {@link Test#timeout()}. */ public class Test014Timeout extends WithNestedTestClass { public static class Nested extends RandomizedTest { @Test(timeout = 100) public void testMethod1() { assumeRunningNested(); sleep(2000); } @Test(timeout = 100) public void testMethod2() { assumeRunningNested(); while (!Thread.interrupted()) { // Do nothing. } } } @Test public void testTimeoutInTestAnnotation() { Result result = JUnitCore.runClasses(Nested.class); Assert.assertEquals(0, result.getIgnoreCount()); Assert.assertEquals(2, result.getRunCount()); Assert.assertEquals(2, result.getFailureCount()); } } Test015TimeoutOverride.java000066400000000000000000000033211235451432000426610ustar00rootroot00000000000000randomizedtesting-release-2.1.6/randomized-runner/src/test/java/com/carrotsearch/randomizedtesting/timeoutspackage com.carrotsearch.randomizedtesting.timeouts; import junit.framework.Assert; import org.junit.After; import org.junit.Test; import org.junit.runner.JUnitCore; import org.junit.runner.Result; import com.carrotsearch.randomizedtesting.RandomizedTest; import com.carrotsearch.randomizedtesting.SysGlobals; import com.carrotsearch.randomizedtesting.WithNestedTestClass; import com.carrotsearch.randomizedtesting.annotations.Timeout; /** * Test global timeout override (-Dtests.timeout=1000!). */ public class Test015TimeoutOverride extends WithNestedTestClass { public static class Nested extends RandomizedTest { @Test @Timeout(millis = 5000) public void testMethod1() { assumeRunningNested(); sleep(10000); } } public static class Nested2 extends RandomizedTest { @Test @Timeout(millis = 100) public void testMethod1() { assumeRunningNested(); sleep(1000); } } @Test public void testTimeoutOverride() { System.setProperty(SysGlobals.SYSPROP_TIMEOUT(), "200!"); long start = System.currentTimeMillis(); Result result = JUnitCore.runClasses(Nested.class); long end = System.currentTimeMillis(); Assert.assertEquals(1, result.getFailureCount()); Assert.assertTrue(end - start < 3000); } @Test public void testDisableTimeout() { System.setProperty(SysGlobals.SYSPROP_TIMEOUT(), "0!"); long start = System.currentTimeMillis(); Result result = JUnitCore.runClasses(Nested2.class); long end = System.currentTimeMillis(); Assert.assertEquals(0, result.getFailureCount()); Assert.assertTrue(end - start > 900); } @After public void cleanup() { System.clearProperty(SysGlobals.SYSPROP_TIMEOUT()); } } Test016ThreadLeaksCustomFilters.java000066400000000000000000000027571235451432000444630ustar00rootroot00000000000000randomizedtesting-release-2.1.6/randomized-runner/src/test/java/com/carrotsearch/randomizedtesting/timeoutspackage com.carrotsearch.randomizedtesting.timeouts; import org.fest.assertions.api.Assertions; import org.junit.Test; import org.junit.runner.JUnitCore; import org.junit.runner.Result; import com.carrotsearch.randomizedtesting.RandomizedTest; import com.carrotsearch.randomizedtesting.ThreadFilter; import com.carrotsearch.randomizedtesting.WithNestedTestClass; import com.carrotsearch.randomizedtesting.annotations.ThreadLeakFilters; import com.carrotsearch.randomizedtesting.annotations.ThreadLeakScope; import com.carrotsearch.randomizedtesting.annotations.ThreadLeakScope.Scope; /** * Checks custom thread ignore policy. */ public class Test016ThreadLeaksCustomFilters extends WithNestedTestClass { public static class FooBarFilter implements ThreadFilter { @Override public boolean reject(Thread t) { return t.getName().contains("foobar"); } } @ThreadLeakScope(Scope.TEST) @ThreadLeakFilters(defaultFilters = true, filters = { FooBarFilter.class }) public static class Nested1 extends RandomizedTest { @Test public void testFooBars() throws Exception { assumeRunningNested(); for (int i = 0; i < 10; i++) { startZombieThread("foobar-" + i); } } } @Test public void testFilteredOnly() throws Throwable { Result r = JUnitCore.runClasses(Nested1.class); Assertions.assertThat(r.getFailures()).isEmpty(); Assertions.assertThat(getLoggingMessages()).isEmpty(); Assertions.assertThat(getSysouts()).isEmpty(); } } Test017ThreadLeaksCustomFiltersException.java000066400000000000000000000026541235451432000463370ustar00rootroot00000000000000randomizedtesting-release-2.1.6/randomized-runner/src/test/java/com/carrotsearch/randomizedtesting/timeoutspackage com.carrotsearch.randomizedtesting.timeouts; import org.junit.Test; import org.junit.runner.JUnitCore; import org.junit.runner.Result; import com.carrotsearch.randomizedtesting.RandomizedRunner; import com.carrotsearch.randomizedtesting.ThreadFilter; import com.carrotsearch.randomizedtesting.Utils; import com.carrotsearch.randomizedtesting.WithNestedTestClass; import com.carrotsearch.randomizedtesting.annotations.ThreadLeakFilters; import com.carrotsearch.randomizedtesting.annotations.ThreadLeakScope; import com.carrotsearch.randomizedtesting.annotations.ThreadLeakScope.Scope; /** * Checks custom thread ignore policy. */ public class Test017ThreadLeaksCustomFiltersException extends WithNestedTestClass { public static class ExceptionFilter implements ThreadFilter { @Override public boolean reject(Thread t) { throw new RuntimeException("filter-exception"); } } @ThreadLeakScope(Scope.TEST) @ThreadLeakFilters(defaultFilters = true, filters = { ExceptionFilter.class }) public static class Nested1 { @Test public void testFooBars() throws Exception { assumeRunningNested(); for (int i = 0; i < 10; i++) { startZombieThread("foobar-" + i); } } } @Test public void testExceptionInFilter() throws Throwable { Result r = new JUnitCore().run(new RandomizedRunner(Nested1.class)); Utils.assertFailureWithMessage(r, "filter-exception"); } } Test018TimeoutStacks.java000066400000000000000000000022131235451432000423340ustar00rootroot00000000000000randomizedtesting-release-2.1.6/randomized-runner/src/test/java/com/carrotsearch/randomizedtesting/timeoutspackage com.carrotsearch.randomizedtesting.timeouts; import org.fest.assertions.api.Assertions; import org.junit.Test; import org.junit.runner.JUnitCore; import com.carrotsearch.randomizedtesting.RandomizedRunner; import com.carrotsearch.randomizedtesting.WithNestedTestClass; import com.carrotsearch.randomizedtesting.annotations.ThreadLeakScope; import com.carrotsearch.randomizedtesting.annotations.ThreadLeakScope.Scope; import com.carrotsearch.randomizedtesting.annotations.TimeoutSuite; /** * Checks custom thread ignore policy. */ public class Test018TimeoutStacks extends WithNestedTestClass { @ThreadLeakScope(Scope.TEST) @TimeoutSuite(millis = 1000) public static class Nested1 { @Test public void testFooBars() throws Exception { assumeRunningNested(); for (int i = 0; i < 5; i++) { startThread("foobar-" + i); } Thread.sleep(5000); } } @Test public void testExceptionInFilter() throws Throwable { new JUnitCore().run(new RandomizedRunner(Nested1.class)); Assertions.assertThat(getLoggingMessages()).contains("sleepForever("); // sysout.println(getLoggingMessages()); } } Test019ThreadLeakGroup.java000066400000000000000000000047231235451432000425670ustar00rootroot00000000000000randomizedtesting-release-2.1.6/randomized-runner/src/test/java/com/carrotsearch/randomizedtesting/timeoutspackage com.carrotsearch.randomizedtesting.timeouts; import java.util.concurrent.CountDownLatch; import org.fest.assertions.api.Assertions; import org.junit.After; import org.junit.Test; import org.junit.runner.JUnitCore; import org.junit.runner.Result; import com.carrotsearch.randomizedtesting.RandomizedTest; import com.carrotsearch.randomizedtesting.Utils; import com.carrotsearch.randomizedtesting.WithNestedTestClass; import com.carrotsearch.randomizedtesting.annotations.ThreadLeakGroup; import com.carrotsearch.randomizedtesting.annotations.ThreadLeakGroup.Group; import com.carrotsearch.randomizedtesting.annotations.ThreadLeakScope; import com.carrotsearch.randomizedtesting.annotations.ThreadLeakScope.Scope; /** * Checks thread leak detection group. */ public class Test019ThreadLeakGroup extends WithNestedTestClass { volatile static Thread t; @ThreadLeakScope(Scope.TEST) @ThreadLeakGroup(Group.TESTGROUP) public static class Nested1 extends RandomizedTest { @Test public void testLeakOutsideOfGroup() throws Exception { assumeRunningNested(); final CountDownLatch latch = new CountDownLatch(1); ThreadGroup newTopGroup = new ThreadGroup(Utils.getTopThreadGroup(), "foobar-group"); t = new Thread(newTopGroup, "foobar") { @Override public void run() { try { latch.countDown(); Thread.sleep(5000); } catch (InterruptedException e) {} } }; t.start(); latch.await(); } } @ThreadLeakGroup(Group.MAIN) public static class Nested2 extends Nested1 { } @ThreadLeakGroup(Group.ALL) public static class Nested3 extends Nested1 { } @Test public void testTestGroup() throws Throwable { Result r = JUnitCore.runClasses(Nested1.class); Assertions.assertThat(r.getFailures()).isEmpty(); Assertions.assertThat(t != null && t.isAlive()).isTrue(); } @Test public void testMainGroup() throws Throwable { Result r = JUnitCore.runClasses(Nested2.class); Assertions.assertThat(r.getFailures()).isEmpty(); Assertions.assertThat(t != null && t.isAlive()).isTrue(); } @Test public void testAll() throws Throwable { Result r = JUnitCore.runClasses(Nested3.class); Utils.assertNoLiveThreadsContaining("foobar"); Utils.assertFailureWithMessage(r, "1 thread leaked from TEST"); } @After public void cleanup() throws Exception { if (t != null) { t.interrupt(); t.join(); t = null; } } }