Skip to content

Commit

Permalink
Merge branch 'master' into ruby-2.4
Browse files Browse the repository at this point in the history
  • Loading branch information
headius committed Nov 17, 2016
2 parents 665521d + a942825 commit 6ea39ea
Show file tree
Hide file tree
Showing 18 changed files with 141 additions and 57 deletions.
1 change: 1 addition & 0 deletions .travis.yml
Expand Up @@ -78,6 +78,7 @@ matrix:
allow_failures:
- env: PHASE='-Pj2ee'
jdk: oraclejdk7
- env: PHASE='-Prake -Dtask=spec:ruby:fast'
# NOTE: build seems to never start (waited for any to finish for more than a day) - probably a travis-ci bug
#- env: PHASE='-Pmain'
# sudo: required
Expand Down
83 changes: 41 additions & 42 deletions BUILDING.md
Expand Up @@ -101,66 +101,75 @@ mvn -pl core
mvn -pl truffle
```


### Day to Day Testing

For normal day-to-day testing, we recommend running the Ruby (MRI) tests
For normal day-to-day testing, we recommend running the Ruby specs. We have set aside a
"fast" grouping that takes only a couple minutes to run:

```
jruby -S rake spec:ruby:fast
```

For a more intensive workout, you can also run the Ruby (MRI) tests
via the following rake command:

```
bin/jruby -S rake test:mri
jruby -S rake test:mri
```

This suite takes a while to complete, so if you want to run an individual file
from MRI's tests (under test/mri), use one of the following commands:

# Run a specific test method in a specific file
```
jruby <test file> -n <specific test method>
```
#### Run a specific test from the MRI suite

# Run a test file with known-failing tests excluded
The MRI suite (under `test/mri`) has a runner script in `test/mri/runner.rb` that sets up
an appropriate test environment. Many of the MRI tests will need to be run via this script.
```
EXCLUDES=test/mri/excludes bin/jruby -r test/mri_test_env.rb test/mri/runner.rb -q -- <test file>
```
#### Run a single spec
```
bin/jruby spec/mspec/bin/mspec run spec/ruby/core/symbol/length_spec.rb
jruby test/mri/runner.rb test/mri/<path to test>
```

#### Run a single spec with remote debugging
```
bin/jruby spec/mspec/bin/mspec run -T-J-agentlib:jdwp=transport=dt_socket,server=y,suspend=y,address=5005 spec/ruby/core/symbol/length_spec.rb
```
You can pass `-v` to the runner for verbose output or `-n test_method_name` to only run a single test method.

#### Run a test file with known-failing tests excluded

The runner script provides a mechanism for "excluding" known failing tests. Ruby scripts under `test/mri/exclude`, named based on the name of the test case's class, exclude with comment tests known to fail.

To run a given test with these excludes enabled, you can use the EXCLUDES environment variable:

Additional tests may be run through mspec.
```
bin/jruby -S mspec -B spec/jruby.2.2.mspec -t bin/jruby -G fails ci <test files>
EXCLUDES=test/mri/excludes bin/jruby test/mri/runner.rb <test file>
```

For more complete assurance, you can also run 1.9 RubySpecs via the
following command:
#### Run a single Ruby spec

Individual specs can be run with the mspec tool:

```
jruby spec/mspec/bin/mspec ci
jruby spec/mspec/bin/mspec ci spec/ruby/<path to spec>
```

And if you are making changes that would affect JRuby's core runtime
or embedding APIs, you should run JRuby's Java-based unit tests via
If `ci` is omitted or replaced with `run` you will see any specs known to fail. The `ci` command
avoids running those specs.

#### Run JRuby with with remote debugging

If you are familiar with Java debuggers, you can attach one to a JRuby process using the JDWP agent.
The exact flag may vary with debugger and platform:

```
mvn -Ptest
bin/jruby -T-J-agentlib:jdwp=transport=dt_socket,server=y,suspend=y,address=5005 <rest of arguments>
```
#### JRuby internal unit tests

On travis the following tests will run
If you are making changes that would affect JRuby's core runtime
or embedding APIs, you should run JRuby's Java-based unit tests via

```
mvn -Ptest
mvn -Prake -Dtask=test:extended
mvn -Prake -Dtask=spec:ci\_interpreted\_travis
mvn -Ptruffle
```

#### Tests for other ways of deploying and packaging JRuby

There are some maven integration tests (i.e. consistency test if all gems are included, osgi test, etc) for the various distributions of JRuby which can be invoked with

```
Expand All @@ -169,21 +178,11 @@ mvn -Pcomplete -Dinvoker.skip=false
mvn -Pdist -Dinvoker.skip=false
```

### Just Like CI

Our [CI](https://travis-ci.org/jruby/jruby) runs the following three commands (in essence):

```
rake test:extended
jruby spec/mspec/bin/mspec ci
jruby --1.8 spec/mspec/bin/mspec ci
```
#### Just Like CI

The complete CI test suite will take anywhere from 20 to 45 minutes to
complete, but provides the most accurate indication of the stability of
your local JRuby source.
JRuby runs CI tests on TravisCI. See [.travis.yml](https://github.com/jruby/jruby/blob/master/.travis.yml).

### maven integration tests - -Pjruby-complete or -Pmain
#### maven integration tests - -Pjruby-complete or -Pmain

maven integration test will use the packed maven artifact to run the tests in a forked maven instance. these maven projects are locatated in

Expand Down
2 changes: 1 addition & 1 deletion core/src/main/java/org/jruby/RubyMath.java
Expand Up @@ -758,7 +758,7 @@ public NemesLogGamma(double x) {
}

double int_part = (int) x;
sign = (int_part % 2 == 0 && (x - int_part) != 0.0 && (x < 0)) ? -1 : 1;
sign = ((x == -0.0) || (int_part % 2 == 0 && (x - int_part) != 0.0 && (x < 0))) ? -1 : 1;
if ((x - int_part) == 0.0 && 0 < int_part && int_part <= FACTORIAL.length) {
value = Math.log(FACTORIAL[(int) int_part - 1]);
}
Expand Down
Expand Up @@ -78,7 +78,39 @@ public static MethodHandle generate(final int size) {
final String clsPath = "org/jruby/runtime/scopes/DynamicScope" + size;
final String clsName = clsPath.replaceAll("/", ".");

// try to load the class, in case we have parallel generation happening
Class p;

try {
p = CDCL.loadClass(clsName);
} catch (ClassNotFoundException cnfe) {
// try again under lock
synchronized (CDCL) {
try {
p = CDCL.loadClass(clsName);
} catch (ClassNotFoundException cnfe2) {
// proceed to actually generate the class
p = generateInternal(size, clsPath, clsName);
}
}
}

// acquire constructor handle and store it
try {
MethodHandle mh = MethodHandles.lookup().findConstructor(p, MethodType.methodType(void.class, StaticScope.class, DynamicScope.class));
mh = mh.asType(MethodType.methodType(DynamicScope.class, StaticScope.class, DynamicScope.class));
MethodHandle previousMH = specializedFactories.putIfAbsent(size, mh);
if (previousMH != null) mh = previousMH;

return mh;
} catch (Exception e) {
throw new RuntimeException(e);
}
}

private static Class generateInternal(final int size, final String clsPath, final String clsName) {
// ensure only one thread will attempt to generate and define the new class
synchronized (CDCL) {
// create a new one
final String[] newFields = varList(size);

Expand Down Expand Up @@ -255,16 +287,7 @@ public static MethodHandle generate(final int size) {
}});
}};

Class p = defineClass(jiteClass);

MethodHandle mh = MethodHandles.lookup().findConstructor(p, MethodType.methodType(void.class, StaticScope.class, DynamicScope.class));
mh = mh.asType(MethodType.methodType(DynamicScope.class, StaticScope.class, DynamicScope.class));
MethodHandle previousMH = specializedFactories.putIfAbsent(size, mh);
if (previousMH != null) mh = previousMH;

return mh;
} catch (Exception e) {
throw new RuntimeException(e);
return defineClass(jiteClass);
}
}

Expand Down Expand Up @@ -310,7 +333,15 @@ private static MethodHandle getClassFromSize(int size) {
}

private static Class defineClass(JiteClass jiteClass) {
return CDCL.defineClass(jiteClass.getClassName().replaceAll("/", "."), jiteClass.toBytes(JDKVersion.V1_7));
return CDCL.defineClass(classNameFromJiteClass(jiteClass), jiteClass.toBytes(JDKVersion.V1_7));
}

private static Class loadClass(JiteClass jiteClass) throws ClassNotFoundException {
return CDCL.loadClass(classNameFromJiteClass(jiteClass));
}

private static String classNameFromJiteClass(JiteClass jiteClass) {
return jiteClass.getClassName().replaceAll("/", ".");
}

private static String[] varList(int size) {
Expand Down
32 changes: 30 additions & 2 deletions core/src/test/java/org/jruby/runtime/TestDynamicScope.java
@@ -1,15 +1,43 @@
package org.jruby.runtime;

import java.lang.invoke.MethodHandle;
import java.util.ArrayList;
import junit.framework.TestCase;
import org.jruby.RubyBasicObject;
import org.jruby.runtime.builtin.IRubyObject;
import org.jruby.runtime.scope.DynamicScopeGenerator;
import org.junit.Assert;
import org.junit.Test;

import java.util.Arrays;

public class TestDynamicScope extends TestCase {
@Test
public void testMultithreadedScopeGeneration() throws Throwable {
final ArrayList<MethodHandle> result = new ArrayList<>();
final int numberOfThreads = 10;

Thread[] threads = new Thread[numberOfThreads];
for(int i = 0; i < numberOfThreads; i++) {
threads[i] = new Thread(new Runnable(){
public void run() {
MethodHandle dynamicScope = DynamicScopeGenerator.generate(10);
synchronized(result) {
result.add(dynamicScope);
}
}
});
threads[i].start();
}

for(int i = 0; i < numberOfThreads; i++) {
threads[i].join();
}

Assert.assertEquals(numberOfThreads, result.size());
for (int i = 0; i < result.size() - 1; ++i) {
Assert.assertEquals(result.get(i), result.get(i+1));
}
}

@Test
public void testScopeGeneration() throws Throwable {
for (int i = 0; i < 100; i++) {
Expand Down
1 change: 1 addition & 0 deletions test/mri/excludes/FTPTest.rb
@@ -1,2 +1,3 @@
exclude :test_abort, ""
exclude :test_list_read_timeout_exceeded, "needs investigation #4303"
exclude :test_status, ""
1 change: 1 addition & 0 deletions test/mri/excludes/TestJSONEncoding.rb
@@ -0,0 +1 @@
exclude :test_parse_ascii_8bit, "produces an error with UTF-8 encoding for invalid bytes, which test/unit tries to split and blows up"
1 change: 1 addition & 0 deletions test/mri/excludes/TestM17N.rb
@@ -1,3 +1,4 @@
exclude :test_greek_capital_gap, "needs investigation #4303"
exclude :test_nonascii_method_name, "lexer is not pulling mbc characters off the wire correctly"
exclude :test_split, "our impl has diverged and does not appear to handle encoded null char properly"
exclude :test_symbol, "management of differently-encoded symbols is not right"
Expand Down
2 changes: 2 additions & 0 deletions test/mri/excludes/TestMarshal.rb
Expand Up @@ -4,7 +4,9 @@
exclude :test_inconsistent_struct, "needs investigation"
exclude :test_marshal_complex, "needs investigation"
exclude :test_marshal_dump_ivar, "needs investigation"
exclude :test_marshal_load_extended_class_crash, "needs investigation #4303"
exclude :test_marshal_load_ivar, "needs investigation"
exclude :test_marshal_load_r_prepare_reference_crash, "needs investigation #4303"
exclude :test_marshal_load_should_not_taint_classes, "needs investigation"
exclude :test_marshal_rational, "needs investigation"
exclude :test_modify_array_during_dump, "needs investigation"
Expand Down
1 change: 1 addition & 0 deletions test/mri/excludes/TestProcess.rb
Expand Up @@ -20,6 +20,7 @@
exclude :test_exec_fd_3_redirect, "requires fork"
#exclude :test_execopts_gid, "doesn't really pass but test seems OK due throwing NotImplementedError"
exclude :test_execopts_open_chdir, "needs investigation"
exclude :test_execopts_open_chdir_m17n_path, "needs investigation #4303"
exclude :test_execopts_open_failure, "may depend on error handling after fork, not possible with posix_spawn"
exclude :test_execopts_pgroup, "#<TypeError: no implicit conversion of false into Integer>"
exclude :test_execopts_popen, "needs investigation"
Expand Down
1 change: 1 addition & 0 deletions test/mri/excludes/TestRipper/Ripper.rb
@@ -0,0 +1 @@
exclude :test_regexp_with_option, "needs investigation #4308"
1 change: 1 addition & 0 deletions test/mri/excludes/TestRubyOptions.rb
Expand Up @@ -5,6 +5,7 @@
exclude :test_dump_yydebug_with_rflag, "needs investigation"
exclude :test_encoding, "needs investigation"
exclude :test_eval, "needs investigation"
exclude :test_frozen_string_literal_debug, "needs investigation #4303"
exclude :test_indentation_check, "needs investigation"
exclude :test_invalid_option, "needs investigation"
exclude :test_kanji, "needs investigation"
Expand Down
1 change: 1 addition & 0 deletions test/mri/excludes/TestStringIO.rb
@@ -0,0 +1 @@
exclude :test_binmode, "needs investigation #4303"
1 change: 1 addition & 0 deletions test/mri/excludes/TestStruct/SubStruct.rb
@@ -1 +1,2 @@
exclude :test_new_dupilicate, 'needs investigation #4303'
exclude :test_nonascii, ''
1 change: 1 addition & 0 deletions test/mri/excludes/TestStruct/TopStruct.rb
@@ -1 +1,2 @@
exclude :test_new_dupilicate, 'needs investigation #4303'
exclude :test_nonascii, ''
3 changes: 2 additions & 1 deletion test/mri/excludes/TestSymbol.rb
@@ -1,6 +1,7 @@
exclude :test_ascii_incomat_inspect, "needs investigation"
exclude :test_inspect, "needs investigation"
#exclude :test_inspect_dollar, "needs investigation"
exclude :test_to_proc_arg, "we have plans to do different caching here, see 69662ab8cd1616a2ee076488226a473648fc6267"
exclude :test_to_proc_binding, "needs investigation #4303"
exclude :test_to_proc_iseq, "needs investigation #4303"
exclude :test_symbol_encoding, "needs investigation"
exclude :test_symbol_fstr_leak, "assert_no_memory_leak fails due an unexpected nil"
12 changes: 12 additions & 0 deletions test/mri/excludes/TestSyntax.rb
@@ -1,10 +1,22 @@
exclude :test__END___cr, "needs investigation"
exclude :test_alias_symbol, "needs investigation #4308"
exclude :test_cmdarg_kwarg_lvar_clashing_method, "needs investigation #4308"
exclude :test_constant_reassignment_nested, "needs investigation"
exclude :test_constant_reassignment_toplevel, "needs investigation"
exclude :test_dedented_heredoc_with_blank_more_indented_line, "needs investigation #4308"
exclude :test_dedented_heredoc_with_indentation, "needs investigation #4308"
exclude :test_dedented_heredoc_with_interpolated_expression, "needs investigation #4308"
exclude :test_dedented_heredoc_with_interpolated_string, "needs investigation #4308"
exclude :test_dedented_heredoc_with_newline, "hangs"
exclude :test_dedented_heredoc_without_indentationsh, "needs investigation #4308"
exclude :test_defined_empty_argument, "needs investigation"
exclude :test_do_block_in_lambda, "needs investigation"
exclude :test_duplicated_when, "needs investigation"
exclude :test_integer_suffix, "needs investigation"
exclude :test_invalid_next, "needs investigation"
exclude :test_null_range_cmdarg, "needs investigation"
exclude :test_syntax_ext, "needs investigation #4308"
exclude :test_syntax_lib, "needs investigation #4308"
exclude :test_syntax_sample, "needs investigation #4308"
exclude :test_syntax_test, "needs investigation #4308"
exclude :test_undef_symbol, "needs investigation #4308"
1 change: 1 addition & 0 deletions test/mri/excludes/TestThread.rb
Expand Up @@ -13,6 +13,7 @@
exclude :test_recursive_outer, "expected to be fixed by our change based on MRI r43981 but was not"
exclude :test_safe_level, "SAFE levels are unsupported"
exclude :test_thread_join_main_thread, "hangs"
exclude :test_thread_setname_in_initialize, "needs investigation #4308"
exclude :test_thread_status_raise_after_kill, "aborting status does not show up as expected"
exclude :test_thread_timer_and_interrupt, "event statuses do not match expected"
exclude :test_thread_variable_in_enumerator, "fibers in JRuby have their own Thread.current"

0 comments on commit 6ea39ea

Please sign in to comment.