[ https://issues.apache.org/jira/browse/HADOOP-9387?page=com.atlassian.jira.plugin.system.issuetabpanels:comment-tabpanel&focusedCommentId=13601817#comment-13601817 ]
Chris Nauroth commented on HADOOP-9387: --------------------------------------- Hi Ivan, Thanks for working on cleaning it up. This code has tripped me up in the past. {code} public String getFilesystem() throws IOException { if (Shell.WINDOWS) { this.filesystem = dirFile.getCanonicalPath().substring(0, 2); return this.filesystem; } else { run(); return filesystem; } } {code} It appears that there is a pitfall if running on non-Windows. If the user of this class calls {{getFilesystem}} before calling {{getMount}}, then {{filesystem}} will be uninitialized. This is because on non-Windows, we assign to the {{filesystem}} member variable inside {{parseOutput}}, which gets called from {{getMount}}, but not {{getFilesystem}}. Perhaps it's safer to move all of the parsing logic back into {{parseExecResult}}. {code} switch(getOSType()) { case OS_TYPE_AIX: Long.parseLong(tokens.nextToken()); // capacity Long.parseLong(tokens.nextToken()); // available Integer.parseInt(tokens.nextToken()); // pct used tokens.nextToken(); tokens.nextToken(); this.mount = tokens.nextToken(); break; case OS_TYPE_WIN: case OS_TYPE_SOLARIS: case OS_TYPE_MAC: case OS_TYPE_UNIX: default: Long.parseLong(tokens.nextToken()); // capacity Long.parseLong(tokens.nextToken()); // used Long.parseLong(tokens.nextToken()); // available Integer.parseInt(tokens.nextToken()); // pct used this.mount = tokens.nextToken(); break; } {code} The patch removes the special handling for AIX, so I think this would cause a regression if running on that platform. I've never used AIX, but what I infer from the old code is that the output of df -k on Linux places mount in column 6, whereas on AIX it goes in column 7. Therefore, we need an extra call to {{StringTokenizer#nextToken}} if running on AIX. Unfortunately, I don't have access to an AIX machine to confirm. Perhaps this code could be simplified to always look at the last column without platform checks and special cases, i.e.: {code} String[] columns = line.split(); this.mount = columns[columns.length - 1]; {code} However, that would be dependent on AIX printing mount in the last column, and without an AIX machine, I can't confirm. I did confirm that the patch works for Windows, so maybe the simplest path forward is to prepare a smaller patch just for fixing Windows, and then file a follow-up jira for future refactoring work. That would give more time to track down someone with access to AIX to help with testing. > TestDFVariations fails on Windows after the merge > ------------------------------------------------- > > Key: HADOOP-9387 > URL: https://issues.apache.org/jira/browse/HADOOP-9387 > Project: Hadoop Common > Issue Type: Bug > Affects Versions: 3.0.0 > Reporter: Ivan Mitic > Assignee: Ivan Mitic > Attachments: HADOOP-9387.trunk.2.patch, HADOOP-9387.trunk.patch > > > Test fails with the following errors: > {code} > Running org.apache.hadoop.fs.TestDFVariations > Tests run: 4, Failures: 0, Errors: 2, Skipped: 0, Time elapsed: 0.186 sec <<< > FAILURE! > testOSParsing(org.apache.hadoop.fs.TestDFVariations) Time elapsed: 109 sec > <<< ERROR! > java.io.IOException: Fewer lines of output than expected > at org.apache.hadoop.fs.DF.parseOutput(DF.java:203) > at org.apache.hadoop.fs.DF.getMount(DF.java:150) > at > org.apache.hadoop.fs.TestDFVariations.testOSParsing(TestDFVariations.java:59) > at sun.reflect.NativeMethodAccessorImpl.invoke0(Native Method) > at > sun.reflect.NativeMethodAccessorImpl.invoke(NativeMethodAccessorImpl.java:39) > at > sun.reflect.DelegatingMethodAccessorImpl.invoke(DelegatingMethodAccessorImpl.java:25) > at java.lang.reflect.Method.invoke(Method.java:597) > at > org.junit.runners.model.FrameworkMethod$1.runReflectiveCall(FrameworkMethod.java:44) > at > org.junit.internal.runners.model.ReflectiveCallable.run(ReflectiveCallable.java:15) > at > org.junit.runners.model.FrameworkMethod.invokeExplosively(FrameworkMethod.java:41) > at > org.junit.internal.runners.statements.InvokeMethod.evaluate(InvokeMethod.java:20) > at > org.junit.internal.runners.statements.FailOnTimeout$1.run(FailOnTimeout.java:28) > testGetMountCurrentDirectory(org.apache.hadoop.fs.TestDFVariations) Time > elapsed: 1 sec <<< ERROR! > java.io.IOException: Fewer lines of output than expected > at org.apache.hadoop.fs.DF.parseOutput(DF.java:203) > at org.apache.hadoop.fs.DF.getMount(DF.java:150) > at > org.apache.hadoop.fs.TestDFVariations.testGetMountCurrentDirectory(TestDFVariations.java:139) > at sun.reflect.NativeMethodAccessorImpl.invoke0(Native Method) > at > sun.reflect.NativeMethodAccessorImpl.invoke(NativeMethodAccessorImpl.java:39) > at > sun.reflect.DelegatingMethodAccessorImpl.invoke(DelegatingMethodAccessorImpl.java:25) > at java.lang.reflect.Method.invoke(Method.java:597) > at > org.junit.runners.model.FrameworkMethod$1.runReflectiveCall(FrameworkMethod.java:44) > at > org.junit.internal.runners.model.ReflectiveCallable.run(ReflectiveCallable.java:15) > at > org.junit.runners.model.FrameworkMethod.invokeExplosively(FrameworkMethod.java:41) > at > org.junit.internal.runners.statements.InvokeMethod.evaluate(InvokeMethod.java:20) > at > org.junit.internal.runners.statements.FailOnTimeout$1.run(FailOnTimeout.java:28) > {code} -- This message is automatically generated by JIRA. If you think it was sent incorrectly, please contact your JIRA administrators For more information on JIRA, see: http://www.atlassian.com/software/jira