JBehave
  1. JBehave
  2. JBEHAVE-1056

ResolveToPackagedName path resolver is broken on Windows

    Details

    • Type: Bug Bug
    • Status: Open Open
    • Priority: Major Major
    • Resolution: Unresolved
    • Affects Version/s: 3.9.5
    • Fix Version/s: 3.10
    • Component/s: Core
    • Labels:
      None
    • Environment:
      Windows 7 x64
      java version "1.7.0_71"
      Java(TM) SE Runtime Environment (build 1.7.0_71-b14)
      Java HotSpot(TM) 64-Bit Server VM (build 24.71-b01, mixed mode)
    • Number of attachments :
      0

      Description

      Current implementation of 'org.jbehave.core.reporters.FilePrintStreamFactory.ResolveToPackagedName' is the following:

          public static class ResolveToPackagedName extends AbstractPathResolver {
      
              public String resolveName(StoryLocation storyLocation , String extension) {
                  String name = storyLocation .getPath().replace('/', '.');
                  if (name .startsWith(".")) {
                      name = name.substring(1);
                  }
                  return StringUtils.substringBeforeLast( name, ".") + "." + extension ;
              }
      
          }
      

      In the case StoryLocation is represented by URL:

      StoryLocation[codeLocation=file:/C:/Users/dpelevin/git/test/build/classes/test/,storyPath=file:/C:/Users/dpelevin/git/test/build/resources/test/stories/test.story,storyPathIsURL=true]
      

      we will get name with unescaped ':' characters:

      C:\Users\dpelevin\git\test\build\classes\jbehave\file:.C:.Users.dpelevin.git.test.build.resources.test.stories.test.stats
      

      Such names are not valid on Windows and JBehave fail with:

      java.io.FileNotFoundException: C:\Users\dpelevin\git\test\build\classes\jbehave\file:.C:.Users.dpelevin.git.test.build.resources.test.stories.test.stats (Syntax error in the file name, directory name, or volume label)
      java.io.FileOutputStream.open(Native Method)
      java.io.FileOutputStream.<init>(FileOutputStream.java:221)
      org.jbehave.core.reporters.FilePrintStreamFactory$FilePrintStream.<init>(FilePrintStreamFactory.java:138)
      org.jbehave.core.reporters.FilePrintStreamFactory.createPrintStream(FilePrintStreamFactory.java:38)
      org.jbehave.core.reporters.Format$9.createStoryReporter(Format.java:108)
      org.jbehave.core.reporters.StoryReporterBuilder.reporterFor(StoryReporterBuilder.java:316)
      org.jbehave.core.reporters.StoryReporterBuilder.build(StoryReporterBuilder.java:292)
      org.jbehave.core.configuration.Configuration.storyReporter(Configuration.java:208)
      org.jbehave.core.embedder.StoryRunner.reporterFor(StoryRunner.java:358), org.jbehave.core.embedder.StoryRunner.runCancellable(StoryRunner.java:235)
      org.jbehave.core.embedder.StoryRunner.run(StoryRunner.java:219), org.jbehave.core.embedder.StoryRunner.run(StoryRunner.java:180)
      org.jbehave.core.embedder.StoryManager$EnqueuedStory.call(StoryManager.java:229)
      org.jbehave.core.embedder.StoryManager$EnqueuedStory.call(StoryManager.java:201)
      java.util.concurrent.FutureTask.run(FutureTask.java:262)
      java.util.concurrent.ThreadPoolExecutor.runWorker(ThreadPoolExecutor.java:1145)
      java.util.concurrent.ThreadPoolExecutor$Worker.run(ThreadPoolExecutor.java:615)
      java.lang.Thread.run(Thread.java:745)
      

      WORKAROUND:
      Use 'org.jbehave.core.reporters.FilePrintStreamFactory.ResolveToSimpleName' instead of 'ResolveToPackagedName'.

      POSSIBLE SOLUTION:
      Use only substring that start from next character after last ':'. In this case we will cut off protocol and disk name, preserving only full path from the disk root.
      Invalid of invalid name:

      C:\Users\dpelevin\git\test\build\classes\jbehave\file:.C:.Users.dpelevin.git.test.build.resources.test.stories.test.stats
      

      we will get valid one:

      C:\Users\dpelevin\git\test\build\classes\jbehave\.Users.dpelevin.git.test.build.resources.test.stories.test.stats
      

        Activity

        Mauro Talevi made changes -
        Field Original Value New Value
        Affects Version/s 3.x [ 16979 ]
        Affects Version/s 3.9.5 [ 20598 ]
        Fix Version/s 3.9.6 [ 20672 ]
        Hide
        Mauro Talevi added a comment -

        Could you please provide an example project reproducing this behaviour, in particular the configuration you use.

        Show
        Mauro Talevi added a comment - Could you please provide an example project reproducing this behaviour, in particular the configuration you use.
        Hide
        Dmitry Pelevin added a comment -

        You can get project with the same configuration at GitHub:

        https://github.com/OpsIT/berlin-clock

        But I need to notice that gradlew.bat from this repository is broken and you have to replace it with gradle.bat from any other source, or just use standalone Gradle.

        Before running this example project update com.ubs.opsit.interviews.BerlinClockFixture class to make test always pass:

        public class BerlinClockFixture {
        //...
            @Then("the clock should look like $")
            public void thenTheClockShouldLookLike(String theExpectedBerlinClockOutput) {
        //        assertThat(berlinClock.convertTime(theTime), is(equalTo(theExpectedBerlinClockOutput)));
            	Assert.assertTrue(true);
            }
        }
        

        After this change you will be able to see failed tests (because of path resolver). Just run:

        gradle check
        

        If you wish to check the fact that the reason of this fail is path resolver - you need to update update com.ubs.opsit.interviews.support.BehaviouralTestEmbedder and replace path resolver with org.jbehave.core.reporters.FilePrintStreamFactory.ResolveToSimpleName implementation:

        public final class BehaviouralTestEmbedder extends ConfigurableEmbedder {
        //...
            static class SandboxStoryReporterBuilder extends StoryReporterBuilder {
        
                public SandboxStoryReporterBuilder() {
                    withCodeLocation(codeLocationFromClass(SandboxStoryReporterBuilder.class));
                    withDefaultFormats();
                    withFormats(HTML, TXT, CONSOLE);
                    withFailureTrace(true);
        // you need to add the following line
                    withPathResolver(new FilePrintStreamFactory.ResolveToSimpleName());
                }
            }
        }
        
        
        Show
        Dmitry Pelevin added a comment - You can get project with the same configuration at GitHub: https://github.com/OpsIT/berlin-clock But I need to notice that gradlew.bat from this repository is broken and you have to replace it with gradle.bat from any other source, or just use standalone Gradle. Before running this example project update com.ubs.opsit.interviews.BerlinClockFixture class to make test always pass: public class BerlinClockFixture { //... @Then( "the clock should look like $" ) public void thenTheClockShouldLookLike( String theExpectedBerlinClockOutput) { // assertThat(berlinClock.convertTime(theTime), is(equalTo(theExpectedBerlinClockOutput))); Assert.assertTrue( true ); } } After this change you will be able to see failed tests (because of path resolver). Just run: gradle check If you wish to check the fact that the reason of this fail is path resolver - you need to update update com.ubs.opsit.interviews.support.BehaviouralTestEmbedder and replace path resolver with org.jbehave.core.reporters.FilePrintStreamFactory.ResolveToSimpleName implementation: public final class BehaviouralTestEmbedder extends ConfigurableEmbedder { //... static class SandboxStoryReporterBuilder extends StoryReporterBuilder { public SandboxStoryReporterBuilder() { withCodeLocation(codeLocationFromClass(SandboxStoryReporterBuilder.class)); withDefaultFormats(); withFormats(HTML, TXT, CONSOLE); withFailureTrace( true ); // you need to add the following line withPathResolver( new FilePrintStreamFactory.ResolveToSimpleName()); } } }

          People

          • Assignee:
            Unassigned
            Reporter:
            Dmitry Pelevin
          • Votes:
            0 Vote for this issue
            Watchers:
            2 Start watching this issue

            Dates

            • Created:
              Updated: