activityworkshop / GpsPrune

GpsPrune is a map-based application for viewing, editing and converting coordinate data from GPS systems.
GNU General Public License v2.0
67 stars 22 forks source link

Failing tests: Probably invalid OpenWeatherMap API key #88

Closed pykereaper closed 9 months ago

pykereaper commented 9 months ago

When I run the unit tests I got two errors with testCurrentWeather() and testForecast(). Both having the same cause.

Could it have something to do with the API key of OpenWeatherMap being invalid?

Stacktrace of the test:

> Task :GpsPrune:test FAILED

InputStream cannot be null
java.lang.IllegalArgumentException: InputStream cannot be null
    at java.xml/javax.xml.parsers.SAXParser.parse(SAXParser.java:193)
    at tim.prune.function.weather.GetWeatherForecastFunction.getCurrentWeather(GetWeatherForecastFunction.java:358)
    at tim.prune.function.weather.ParsingTest.testCurrentWeather(ParsingTest.java:39)
    at java.base/jdk.internal.reflect.NativeMethodAccessorImpl.invoke0(Native Method)
    at java.base/jdk.internal.reflect.NativeMethodAccessorImpl.invoke(NativeMethodAccessorImpl.java:77)
    at java.base/jdk.internal.reflect.DelegatingMethodAccessorImpl.invoke(DelegatingMethodAccessorImpl.java:43)
    at java.base/java.lang.reflect.Method.invoke(Method.java:568)
    at org.junit.platform.commons.util.ReflectionUtils.invokeMethod(ReflectionUtils.java:688)
    at org.junit.jupiter.engine.execution.MethodInvocation.proceed(MethodInvocation.java:60)
    at org.junit.jupiter.engine.execution.InvocationInterceptorChain$ValidatingInvocation.proceed(InvocationInterceptorChain.java:131)
    at org.junit.jupiter.engine.extension.TimeoutExtension.intercept(TimeoutExtension.java:149)
    at org.junit.jupiter.engine.extension.TimeoutExtension.interceptTestableMethod(TimeoutExtension.java:140)
    at org.junit.jupiter.engine.extension.TimeoutExtension.interceptTestMethod(TimeoutExtension.java:84)
    at org.junit.jupiter.engine.execution.ExecutableInvoker$ReflectiveInterceptorCall.lambda$ofVoidMethod$0(ExecutableInvoker.java:115)
    at org.junit.jupiter.engine.execution.ExecutableInvoker.lambda$invoke$0(ExecutableInvoker.java:105)
    at org.junit.jupiter.engine.execution.InvocationInterceptorChain$InterceptedInvocation.proceed(InvocationInterceptorChain.java:106)
    at org.junit.jupiter.engine.execution.InvocationInterceptorChain.proceed(InvocationInterceptorChain.java:64)
    at org.junit.jupiter.engine.execution.InvocationInterceptorChain.chainAndInvoke(InvocationInterceptorChain.java:45)
    at org.junit.jupiter.engine.execution.InvocationInterceptorChain.invoke(InvocationInterceptorChain.java:37)
    at org.junit.jupiter.engine.execution.ExecutableInvoker.invoke(ExecutableInvoker.java:104)
    at org.junit.jupiter.engine.execution.ExecutableInvoker.invoke(ExecutableInvoker.java:98)
    at org.junit.jupiter.engine.descriptor.TestMethodTestDescriptor.lambda$invokeTestMethod$6(TestMethodTestDescriptor.java:210)
    at org.junit.platform.engine.support.hierarchical.ThrowableCollector.execute(ThrowableCollector.java:73)
    at org.junit.jupiter.engine.descriptor.TestMethodTestDescriptor.invokeTestMethod(TestMethodTestDescriptor.java:206)
    at org.junit.jupiter.engine.descriptor.TestMethodTestDescriptor.execute(TestMethodTestDescriptor.java:131)
    at org.junit.jupiter.engine.descriptor.TestMethodTestDescriptor.execute(TestMethodTestDescriptor.java:65)
    at org.junit.platform.engine.support.hierarchical.NodeTestTask.lambda$executeRecursively$5(NodeTestTask.java:139)
    at org.junit.platform.engine.support.hierarchical.ThrowableCollector.execute(ThrowableCollector.java:73)
    at org.junit.platform.engine.support.hierarchical.NodeTestTask.lambda$executeRecursively$7(NodeTestTask.java:129)
    at org.junit.platform.engine.support.hierarchical.Node.around(Node.java:137)
    at org.junit.platform.engine.support.hierarchical.NodeTestTask.lambda$executeRecursively$8(NodeTestTask.java:127)
    at org.junit.platform.engine.support.hierarchical.ThrowableCollector.execute(ThrowableCollector.java:73)
    at org.junit.platform.engine.support.hierarchical.NodeTestTask.executeRecursively(NodeTestTask.java:126)
    at org.junit.platform.engine.support.hierarchical.NodeTestTask.execute(NodeTestTask.java:84)
    at java.base/java.util.ArrayList.forEach(ArrayList.java:1511)
    at org.junit.platform.engine.support.hierarchical.SameThreadHierarchicalTestExecutorService.invokeAll(SameThreadHierarchicalTestExecutorService.java:38)
    at org.junit.platform.engine.support.hierarchical.NodeTestTask.lambda$executeRecursively$5(NodeTestTask.java:143)
    at org.junit.platform.engine.support.hierarchical.ThrowableCollector.execute(ThrowableCollector.java:73)
    at org.junit.platform.engine.support.hierarchical.NodeTestTask.lambda$executeRecursively$7(NodeTestTask.java:129)
    at org.junit.platform.engine.support.hierarchical.Node.around(Node.java:137)
    at org.junit.platform.engine.support.hierarchical.NodeTestTask.lambda$executeRecursively$8(NodeTestTask.java:127)
    at org.junit.platform.engine.support.hierarchical.ThrowableCollector.execute(ThrowableCollector.java:73)
    at org.junit.platform.engine.support.hierarchical.NodeTestTask.executeRecursively(NodeTestTask.java:126)
    at org.junit.platform.engine.support.hierarchical.NodeTestTask.execute(NodeTestTask.java:84)
    at java.base/java.util.ArrayList.forEach(ArrayList.java:1511)
    at org.junit.platform.engine.support.hierarchical.SameThreadHierarchicalTestExecutorService.invokeAll(SameThreadHierarchicalTestExecutorService.java:38)
    at org.junit.platform.engine.support.hierarchical.NodeTestTask.lambda$executeRecursively$5(NodeTestTask.java:143)
    at org.junit.platform.engine.support.hierarchical.ThrowableCollector.execute(ThrowableCollector.java:73)
    at org.junit.platform.engine.support.hierarchical.NodeTestTask.lambda$executeRecursively$7(NodeTestTask.java:129)
    at org.junit.platform.engine.support.hierarchical.Node.around(Node.java:137)
    at org.junit.platform.engine.support.hierarchical.NodeTestTask.lambda$executeRecursively$8(NodeTestTask.java:127)
    at org.junit.platform.engine.support.hierarchical.ThrowableCollector.execute(ThrowableCollector.java:73)
    at org.junit.platform.engine.support.hierarchical.NodeTestTask.executeRecursively(NodeTestTask.java:126)
    at org.junit.platform.engine.support.hierarchical.NodeTestTask.execute(NodeTestTask.java:84)
    at org.junit.platform.engine.support.hierarchical.SameThreadHierarchicalTestExecutorService.submit(SameThreadHierarchicalTestExecutorService.java:32)
    at org.junit.platform.engine.support.hierarchical.HierarchicalTestExecutor.execute(HierarchicalTestExecutor.java:57)
    at org.junit.platform.engine.support.hierarchical.HierarchicalTestEngine.execute(HierarchicalTestEngine.java:51)
    at org.junit.platform.launcher.core.EngineExecutionOrchestrator.execute(EngineExecutionOrchestrator.java:107)
    at org.junit.platform.launcher.core.EngineExecutionOrchestrator.execute(EngineExecutionOrchestrator.java:88)
    at org.junit.platform.launcher.core.EngineExecutionOrchestrator.lambda$execute$0(EngineExecutionOrchestrator.java:54)
    at org.junit.platform.launcher.core.EngineExecutionOrchestrator.withInterceptedStreams(EngineExecutionOrchestrator.java:67)
    at org.junit.platform.launcher.core.EngineExecutionOrchestrator.execute(EngineExecutionOrchestrator.java:52)
    at org.junit.platform.launcher.core.DefaultLauncher.execute(DefaultLauncher.java:114)
    at org.junit.platform.launcher.core.DefaultLauncher.execute(DefaultLauncher.java:86)
    at org.junit.platform.launcher.core.DefaultLauncherSession$DelegatingLauncher.execute(DefaultLauncherSession.java:86)
    at org.gradle.api.internal.tasks.testing.junitplatform.JUnitPlatformTestClassProcessor$CollectAllTestClassesExecutor.processAllTestClasses(JUnitPlatformTestClassProcessor.java:110)
    at org.gradle.api.internal.tasks.testing.junitplatform.JUnitPlatformTestClassProcessor$CollectAllTestClassesExecutor.access$000(JUnitPlatformTestClassProcessor.java:90)
    at org.gradle.api.internal.tasks.testing.junitplatform.JUnitPlatformTestClassProcessor.stop(JUnitPlatformTestClassProcessor.java:85)
    at org.gradle.api.internal.tasks.testing.SuiteTestClassProcessor.stop(SuiteTestClassProcessor.java:62)
    at java.base/jdk.internal.reflect.NativeMethodAccessorImpl.invoke0(Native Method)
    at java.base/jdk.internal.reflect.NativeMethodAccessorImpl.invoke(NativeMethodAccessorImpl.java:77)
    at java.base/jdk.internal.reflect.DelegatingMethodAccessorImpl.invoke(DelegatingMethodAccessorImpl.java:43)
    at java.base/java.lang.reflect.Method.invoke(Method.java:568)
    at org.gradle.internal.dispatch.ReflectionDispatch.dispatch(ReflectionDispatch.java:36)
    at org.gradle.internal.dispatch.ReflectionDispatch.dispatch(ReflectionDispatch.java:24)
    at org.gradle.internal.dispatch.ContextClassLoaderDispatch.dispatch(ContextClassLoaderDispatch.java:33)
    at org.gradle.internal.dispatch.ProxyDispatchAdapter$DispatchingInvocationHandler.invoke(ProxyDispatchAdapter.java:94)
    at jdk.proxy1/jdk.proxy1.$Proxy2.stop(Unknown Source)
    at org.gradle.api.internal.tasks.testing.worker.TestWorker$3.run(TestWorker.java:193)
    at org.gradle.api.internal.tasks.testing.worker.TestWorker.executeAndMaintainThreadName(TestWorker.java:129)
    at org.gradle.api.internal.tasks.testing.worker.TestWorker.execute(TestWorker.java:100)
    at org.gradle.api.internal.tasks.testing.worker.TestWorker.execute(TestWorker.java:60)
    at org.gradle.process.internal.worker.child.ActionExecutionWorker.execute(ActionExecutionWorker.java:56)
    at org.gradle.process.internal.worker.child.SystemApplicationClassLoaderWorker.call(SystemApplicationClassLoaderWorker.java:113)
    at org.gradle.process.internal.worker.child.SystemApplicationClassLoaderWorker.call(SystemApplicationClassLoaderWorker.java:65)
    at worker.org.gradle.process.internal.worker.GradleWorkerMain.run(GradleWorkerMain.java:69)
    at worker.org.gradle.process.internal.worker.GradleWorkerMain.main(GradleWorkerMain.java:74)
activityworkshop commented 9 months ago

when I run GpsPrune, I can get a weather forecast for a point just fine so I don't think there's a problem with the API key.

when I run the unit tests, it doesn't use the openweathermap server or the API key, so that can't be the problem.

when I call the service by entering a suitable URL in the browser (including the valid API key), then I get valid XML back, with no errors.

I'm not sure what you're trying to do.

pykereaper commented 9 months ago

I didn't deeply evaluate what the problem is, so maybe my suspicion of an invalid OpenWeatherMap API key was a bit hasty. Sorry if I cause confusion.

Nevertheless, Unit tests definitely fail. I'm using Gradle and if I run gradle test, those two tests fail:

/dev/GpsPrune$ gradle test

> Task :test

ParsingTest > testCurrentWeather() FAILED
    java.lang.IllegalArgumentException at ParsingTest.java:39

ParsingTest > testForecast() FAILED
    java.lang.IllegalArgumentException at ParsingTest.java:57

177 tests completed, 2 failed

> Task :test FAILED

FAILURE: Build failed with an exception.

* What went wrong:
Execution failed for task ':test'.

I already pasted the stack trace of one of the failed tests.

I will take some time to investigate and hopefully find the cause.

Can you assure, that tim.prune.function.weather.ParsingTest.testCurrentWeather() and tim.prune.function.weather.ParsingTest.testForecast() are succeeding with you?

pykereaper commented 9 months ago

Alright. Found the reason for the InputStream cannot be null exception. Let's just use the failed testForecast() as an example.

You set a new FileStreamStreamProvider as StreamProvider: https://github.com/activityworkshop/GpsPrune/blob/06d9ff3e10971bd586137862d93103adb1a2a0f7/test/tim/prune/function/weather/ParsingTest.java#L38

And FileStreamProvider couldn't be more simple: https://github.com/activityworkshop/GpsPrune/blob/06d9ff3e10971bd586137862d93103adb1a2a0f7/test/tim/prune/function/weather/FileStreamProvider.java#L19

It just opens the file xml/examplecurrentweather.xml, provided from the Java resources. This file resides in test/tim/prune/function/weather/xml/examplecurrentweather.xml: https://github.com/activityworkshop/GpsPrune/blob/06d9ff3e10971bd586137862d93103adb1a2a0f7/test/tim/prune/function/weather/xml/examplecurrentweather.xml#L1


But that location has to be declared as a resource directory in the Gradle build script. (And also in the Maven one). I'll provide a merge request, that fixes that.

activityworkshop commented 9 months ago

... that location has to be declared as a resource directory in the Gradle build script. (And also in the Maven one).

This sounds like yet another example of where everything runs fine without Gradle or Maven, but with Gradle or Maven then it doesn't work. If you don't use Gradle or Maven then the unit tests run just fine because they can find these xml files without any problems.

Thanks for the patch, I assume that means that there isn't a large number of Gradle/Maven users who have run any unit tests in the last years!

pykereaper commented 9 months ago

Maven & Gradle projects usually have a different folder structure. e.g.:

.
└── src
    ├── main
    │   ├── java
    │   │   └── tim
    │   │       └── prune
    │   └── resources
    │       └── tim
    │           └── prune
    └── test
        ├── java
        │   └── tim
        │       └── prune
        └── resources
            └── tim
                └── prune

The resources and java folder are declared by default. But for uncommon folder structures, one can change the setup, like we had to do here. The fact that folders have to be declared probably can have some advantages regarding build optimization.

Anyway, what I want to say is: Lets not start a war which build system is superior. I'd just say there's a reason, Ant got superseded by Maven and Maven basically got replaced by Gradle. But that doesn't mean the "old" systems are bad. In the end, all comes down to the use case. I imagine, you are perfectly happy with Ant or the Eclipse build system. Because it's just this isolated project. But let's just imagine this project becoming part of a larger build. Maybe one across several Git repositories. A more flexible build system like Gradle, with its support for multi-project-builds, can definitely simplify things.

Thanks for merging! :)