Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

ApolloTestSupport causes issue after upgrading from 1.0.7 to 1.1.2 #2982

Closed
lorderster opened this issue Apr 26, 2023 · 30 comments · Fixed by apollographql/apollo-ios-dev#362
Labels
bug Generally incorrect behavior needs investigation

Comments

@lorderster
Copy link

Summary

Using Swift Package Manager, after updating from 1.0.7 to 1.1.2, the import of ApolloTestSupport causes the archive process failure.
The build process is still working.

Version

1.1.2

Steps to reproduce the behavior
Import ApolloTestSupport in any file, and the following code from TestMock.swift will generate an error:

#if !COCOAPODS
@_exported @testable import ApolloAPI
@testable import Apollo
#endif

Error: Module 'ApolloAPI' was not compiled for testing

@tobiasvelvang
Copy link

I'm currently facing this issue as well.

@sisomollov
Copy link

I have the same problem. Additionally, the error appears when I run the test target.

@lorderster
Copy link
Author

duplicated of #2985

@lorderster lorderster closed this as not planned Won't fix, can't repro, duplicate, stale Apr 27, 2023
@calvincestari calvincestari added bug Generally incorrect behavior needs investigation labels Apr 27, 2023
@calvincestari
Copy link
Member

Reopening this as the original issue, no need to duplicate it elsewhere, and there might be others subscribed to notifications for this issue.

@calvincestari calvincestari reopened this Apr 27, 2023
@calvincestari
Copy link
Member

This seems related to #2933.

@AnthonyMDev
Copy link
Contributor

I'm so confused by this... Why would this cause an issue during archiving when the TestMocks are in a test support target. This target should not even be being built for archive builds. @calvincestari lets get on a call and chat about this one soon.

@wiedem
Copy link

wiedem commented May 5, 2023

I don't necessarily think this ticket is identical to #2933, but note my comments in that ticket anyway. Maybe they will help you here as well.

@lorderster
Copy link
Author

I don't necessarily think this ticket is identical to #2933, but note my comments in that ticket anyway. Maybe they will help you here as well.

I have three different release configurations to switch the environment in my project: Release Development, Release Staging, and Release Production. I'm encountering the mentioned issue only in the Staging and Production configurations.

Note: the issue is still present with version 1.2.0.

@wiedem
Copy link

wiedem commented May 24, 2023

I have three different release configurations to switch the environment in my project: Release Development, Release Staging, and Release Production. I'm encountering the mentioned issue only in the Staging and Production configurations.

Have you checked if any of your release builds / configurations directly or indirectly include any of Apollo's generated mock or test packages?
If that is the case, that is one reason why this leads to said error. This also includes ApolloTestSupport which may not be imported into any of your release builds.

So the first step I can recommend you is to make sure that no Apollo test packages are imported or used for your release builds.

The other case I described is when you use test builds with a different configuration that is not called "Debug" or whose name does not start with "Debug_".

@calvincestari
Copy link
Member

@lorderster, I assume it's just the backend URL and auth that's changing between the configurations? I'm curious why it would work in one but not the others.

@lorderster
Copy link
Author

I have three different release configurations to switch the environment in my project: Release Development, Release Staging, and Release Production. I'm encountering the mentioned issue only in the Staging and Production configurations.

Have you checked if any of your release builds / configurations directly or indirectly include any of Apollo's generated mock or test packages? If that is the case, that is one reason why this leads to said error. This also includes ApolloTestSupport which may not be imported into any of your release builds.

So the first step I can recommend you is to make sure that no Apollo test packages are imported or used for your release builds.

The other case I described is when you use test builds with a different configuration that is not called "Debug" or whose name does not start with "Debug_".

Unfortunately, we are currently importing ApolloTestSupport to create mock responses for UITests when launching the app. We are aware that creating mocks outside of the test target is not the best approach and we are actively searching for an alternative solution to run UITests using mock responses without importing ApolloTestSupport into the main project target.

@lorderster, I assume it's just the backend URL and auth that's changing between the configurations? I'm curious why it would work in one but not the others.

@calvincestari, yes, we use configurations combined with schemas. The schema defines the environment from a visual perspective. Then, we use configurations linked to each schema to define backend URLs, other endpoints in general, bundle identifier, app icon, and certificates/profiles. Me too, I don't understand why the archive is working fine using the configuration "Release Development", instead it fails with "Release Staging" and "Release Production".

@calvincestari
Copy link
Member

We are aware that creating mocks outside of the test target is not the best approach and we are actively searching for an alternative solution to run UITests using mock responses without importing ApolloTestSupport into the main project target.

Have you tried the new selection set initializers? Do they not work for your use case?

@lorderster
Copy link
Author

We are aware that creating mocks outside of the test target is not the best approach and we are actively searching for an alternative solution to run UITests using mock responses without importing ApolloTestSupport into the main project target.

Have you tried the new selection set initializers? Do they not work for your use case?

thank you @calvincestari for the suggestion.
The issue is resolved with the new selection set initializers, as we no longer need to import ApolloTestSupport in the main app target.

@jostster
Copy link

jostster commented Jun 2, 2023

Well I'm having this issue as well. It seems just import ApolloTestSupport in the test Target causes this.

image

@wiedem
Copy link

wiedem commented Jun 2, 2023

Well I'm having this issue as well. It seems just import ApolloTestSupport in the test Target causes this.

See my previous comments here and here. The issue is the configuration name DevStage of your project.
You have to change the name to Debug or prefix it with Debug_. For example Debug_DevStage.
It's a limitation of how Swift packages are compiled.

@jostster
Copy link

jostster commented Jun 2, 2023

Thanks, that seemed to resolve that issue!

@calvincestari
Copy link
Member

You have to change the name to Debug or prefix it with Debug_. For example Debug_DevStage.
It's a limitation of how Swift packages are compiled.

Does anyone have a link to a Swift forum topic or documentation that provides a bit more insight into why this is needed?

@jostster
Copy link

jostster commented Jun 2, 2023

You have to change the name to Debug or prefix it with Debug_. For example Debug_DevStage.
It's a limitation of how Swift packages are compiled.

Does anyone have a link to a Swift forum topic or documentation that provides a bit more insight into why this is needed?

https://forums.swift.org/t/update-spm-to-support-custom-configuration-names/43075

@wiedem
Copy link

wiedem commented Jun 2, 2023

Does anyone have a link to a Swift forum topic or documentation that provides a bit more insight into why this is needed?

You do realize that I've already given you an answer to this question a month ago?

@wiedem
Copy link

wiedem commented Jun 2, 2023

Thanks, that seemed to resolve that issue!

Just as a note, since you should be aware of this: renaming the configuration this way will cause the Swift packages to compile in debug mode, even though your app itself may not compile in debug mode.

This is something you obviously don't want for delivering apps in release mode.
I.e. you should only do this for test and debug builds.

@jostster
Copy link

jostster commented Jun 2, 2023

Thanks for that note. Yes I just renamed our Testing to Debug_Testing

@calvincestari
Copy link
Member

Does anyone have a link to a Swift forum topic or documentation that provides a bit more insight into why this is needed?

You do realize that I've already given you an answer to this question a month ago?

I hadn't realized but thank you.

@jostster
Copy link

jostster commented Jun 30, 2023

Just a bit of an update this doesn't seem to fix the issue as it has come back a few times and takes me having to play around a bunch with removing testability on everything, cleaning derived data and build folder about 50 times for it to work. Then it will work for a bit when trying to use SwiftUI Previews then come back randomly.

I've also added the ApolloAPI and ApolloTestSupport framework to the libraries for just the test target and still will show it when not even running tests.
I found https://developer.apple.com/forums/thread/691908 which my be a cause for this issue.

This apollo upgrade has become such a headache :(

@AnthonyMDev
Copy link
Contributor

I'm sorry you're having such a painful experience @jostster.

I think we're seeing that the TestMocks are causing a lot of headaches for people due to the Diamond Problem linking issues and SwiftUI preview code being built in the application targets.

I'm hoping mergable libraries make this a bit easier in coming months, but I'm feeling more and more that TestMocks aren't the great solution I hoped they would be. Moving back to just enabled the generated initializers on your selection set models and using those for mocking is seeming to be a lot less error prone for most people.

@jostster
Copy link

jostster commented Jul 5, 2023

@AnthonyMDev Thank you for the response. So we aren't specifically using any TestMocks however, if we do not include the ApolloTestSupport in our test target libraries, we get errors when running tests in the constructRequest for RequestChainNetworkTransport.
image
With the console showing the error of failed to demangle superclass of JSONRequest from mangled name '�EY?': subject type x does not conform to protocol GraphQLOperation. The mangled name seems to always change every run.

@AnthonyMDev
Copy link
Contributor

Whoa what?? That is very unexpected...

There is nothing in ApolloTestSupport that even references GraphQLOperation or JSONRequest. It makes no sense that this would be causing this error. It feels like you must have some weird linking going on in your project that is causing this. It's an error I've never even seen before, but failing to demangle due to a protocol non-conformance seems very linker-related to me.

To be clear, what you are experiencing here is different from what this issue thread is about. It's also something that has not ever been reported before.

@jostster Any way that you can provide me an example project with a reproduction of this? I'm not sure how to even start looking into this without a reproduction.

@jostster
Copy link

jostster commented Jul 5, 2023

@AnthonyMDev I don't have a test project, however, I did go in and check our linking and removed our generated Apollo API library from our test target. This allowed our tests to pass without erroring out on the JSONRequest.

@BobaFetters
Copy link
Member

BobaFetters commented Jul 5, 2023

@AnthonyMDev @jostster If I had to guess when the error appeared:

failed to demangle superclass of JSONRequest from mangled name '�EY?': subject type x does not conform to protocol GraphQLOperation

Above it in the logs there was likely something like:
objc[97411]: Class {symbol} is implemented in both {libraryA} and {libraryB}

Which is the diamond dependency issue we have seen come up in other issues that @AnthonyMDev mentioned. Especially if removing ApolloAPI caused it to work then it was likely getting linked twice.

@AnthonyMDev
Copy link
Contributor

This should be fixed by #362 which will be released within the next week.

If you are still experiencing this bug once that is released, please let us know!

Copy link
Contributor

Do you have any feedback for the maintainers? Please tell us by taking a one-minute survey. Your responses will help us understand Apollo iOS usage and allow us to serve you better.

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
Labels
bug Generally incorrect behavior needs investigation
Projects
None yet
Development

Successfully merging a pull request may close this issue.

8 participants