diff --git a/Xamarin.iOS.sln b/Xamarin.iOS.sln index 2d650fb19122..0974e169d97a 100644 --- a/Xamarin.iOS.sln +++ b/Xamarin.iOS.sln @@ -15,6 +15,16 @@ Project("{FAE04EC0-301F-11D3-BF4B-00C04F79EFBC}") = "libmonotouch", "runtime\lib EndProject Project("{FAE04EC0-301F-11D3-BF4B-00C04F79EFBC}") = "xamios", "src\xamios.csproj", "{E1F334C3-8F77-46C9-A28B-A8E9BAEA9FE5}" EndProject +Project("{FAE04EC0-301F-11D3-BF4B-00C04F79EFBC}") = "BundledResources", "tests\linker-ios\BundledResources\BundledResources.csproj", "{FE6EDEE9-ADF6-4F42-BCF2-B68C0A44EC3D}" +EndProject +Project("{FAE04EC0-301F-11D3-BF4B-00C04F79EFBC}") = "link all", "tests\linker-ios\link all\link all.csproj", "{370CC763-EDC3-41DA-A21A-D4C82CABEFE4}" +EndProject +Project("{FAE04EC0-301F-11D3-BF4B-00C04F79EFBC}") = "bindings-test", "tests\bindings-test\bindings-test.csproj", "{D6667423-EDD8-4B50-9D98-1AC5D8A8A4EA}" +EndProject +Project("{FAE04EC0-301F-11D3-BF4B-00C04F79EFBC}") = "link sdk", "tests\linker-ios\link sdk\link sdk.csproj", "{C47F8F72-A7CA-4149-AA7D-BC4814803EF3}" +EndProject +Project("{FAE04EC0-301F-11D3-BF4B-00C04F79EFBC}") = "dont link", "tests\linker-ios\dont link\dont link.csproj", "{839212D5-C25B-4284-AA96-59C3872B8184}" +EndProject Global GlobalSection(SolutionConfigurationPlatforms) = preSolution Debug|Any CPU = Debug|Any CPU @@ -240,8 +250,157 @@ Global {E1F334C3-8F77-46C9-A28B-A8E9BAEA9FE5}.Release|iPhone.Build.0 = Release|Any CPU {E1F334C3-8F77-46C9-A28B-A8E9BAEA9FE5}.DebugStaticRegistrar|iPhone.ActiveCfg = Debug|Any CPU {E1F334C3-8F77-46C9-A28B-A8E9BAEA9FE5}.DebugStaticRegistrar|iPhone.Build.0 = Debug|Any CPU + {FE6EDEE9-ADF6-4F42-BCF2-B68C0A44EC3D}.Debug|iPhoneSimulator.ActiveCfg = Debug|Any CPU + {FE6EDEE9-ADF6-4F42-BCF2-B68C0A44EC3D}.Debug|iPhoneSimulator.Build.0 = Debug|Any CPU + {FE6EDEE9-ADF6-4F42-BCF2-B68C0A44EC3D}.Release|iPhoneSimulator.ActiveCfg = Release|Any CPU + {FE6EDEE9-ADF6-4F42-BCF2-B68C0A44EC3D}.Release|iPhoneSimulator.Build.0 = Release|Any CPU + {FE6EDEE9-ADF6-4F42-BCF2-B68C0A44EC3D}.Debug|iPhone.ActiveCfg = Debug|Any CPU + {FE6EDEE9-ADF6-4F42-BCF2-B68C0A44EC3D}.Debug|iPhone.Build.0 = Debug|Any CPU + {FE6EDEE9-ADF6-4F42-BCF2-B68C0A44EC3D}.Release|iPhone.ActiveCfg = Release|Any CPU + {FE6EDEE9-ADF6-4F42-BCF2-B68C0A44EC3D}.Release|iPhone.Build.0 = Release|Any CPU + {370CC763-EDC3-41DA-A21A-D4C82CABEFE4}.Debug|Any CPU.ActiveCfg = Debug|iPhoneSimulator + {370CC763-EDC3-41DA-A21A-D4C82CABEFE4}.Debug|Any CPU.Build.0 = Debug|iPhoneSimulator + {370CC763-EDC3-41DA-A21A-D4C82CABEFE4}.Release|Any CPU.ActiveCfg = Release|iPhoneSimulator + {370CC763-EDC3-41DA-A21A-D4C82CABEFE4}.Release|Any CPU.Build.0 = Release|iPhoneSimulator + {370CC763-EDC3-41DA-A21A-D4C82CABEFE4}.net_2_0_Debug|Any CPU.ActiveCfg = Debug|iPhoneSimulator + {370CC763-EDC3-41DA-A21A-D4C82CABEFE4}.net_2_0_Debug|Any CPU.Build.0 = Debug|iPhoneSimulator + {370CC763-EDC3-41DA-A21A-D4C82CABEFE4}.net_2_0_Release|Any CPU.ActiveCfg = Debug|iPhoneSimulator + {370CC763-EDC3-41DA-A21A-D4C82CABEFE4}.net_2_0_Release|Any CPU.Build.0 = Debug|iPhoneSimulator + {370CC763-EDC3-41DA-A21A-D4C82CABEFE4}.net_3_5_Debug|Any CPU.ActiveCfg = Debug|iPhoneSimulator + {370CC763-EDC3-41DA-A21A-D4C82CABEFE4}.net_3_5_Debug|Any CPU.Build.0 = Debug|iPhoneSimulator + {370CC763-EDC3-41DA-A21A-D4C82CABEFE4}.net_3_5_Release|Any CPU.ActiveCfg = Debug|iPhoneSimulator + {370CC763-EDC3-41DA-A21A-D4C82CABEFE4}.net_3_5_Release|Any CPU.Build.0 = Debug|iPhoneSimulator + {370CC763-EDC3-41DA-A21A-D4C82CABEFE4}.net_4_0_Debug|Any CPU.ActiveCfg = Debug|iPhoneSimulator + {370CC763-EDC3-41DA-A21A-D4C82CABEFE4}.net_4_0_Debug|Any CPU.Build.0 = Debug|iPhoneSimulator + {370CC763-EDC3-41DA-A21A-D4C82CABEFE4}.net_4_0_Release|Any CPU.ActiveCfg = Debug|iPhoneSimulator + {370CC763-EDC3-41DA-A21A-D4C82CABEFE4}.net_4_0_Release|Any CPU.Build.0 = Debug|iPhoneSimulator + {370CC763-EDC3-41DA-A21A-D4C82CABEFE4}.silverlight_Debug|Any CPU.ActiveCfg = Debug|iPhoneSimulator + {370CC763-EDC3-41DA-A21A-D4C82CABEFE4}.silverlight_Debug|Any CPU.Build.0 = Debug|iPhoneSimulator + {370CC763-EDC3-41DA-A21A-D4C82CABEFE4}.silverlight_Release|Any CPU.ActiveCfg = Debug|iPhoneSimulator + {370CC763-EDC3-41DA-A21A-D4C82CABEFE4}.silverlight_Release|Any CPU.Build.0 = Debug|iPhoneSimulator + {370CC763-EDC3-41DA-A21A-D4C82CABEFE4}.winphone_Debug|Any CPU.ActiveCfg = Debug|iPhoneSimulator + {370CC763-EDC3-41DA-A21A-D4C82CABEFE4}.winphone_Debug|Any CPU.Build.0 = Debug|iPhoneSimulator + {370CC763-EDC3-41DA-A21A-D4C82CABEFE4}.winphone_Release|Any CPU.ActiveCfg = Debug|iPhoneSimulator + {370CC763-EDC3-41DA-A21A-D4C82CABEFE4}.winphone_Release|Any CPU.Build.0 = Debug|iPhoneSimulator + {370CC763-EDC3-41DA-A21A-D4C82CABEFE4}.Debug|iPhoneSimulator.ActiveCfg = Debug|iPhoneSimulator + {370CC763-EDC3-41DA-A21A-D4C82CABEFE4}.Debug|iPhoneSimulator.Build.0 = Debug|iPhoneSimulator + {370CC763-EDC3-41DA-A21A-D4C82CABEFE4}.Release|iPhoneSimulator.ActiveCfg = Release|iPhoneSimulator + {370CC763-EDC3-41DA-A21A-D4C82CABEFE4}.Release|iPhoneSimulator.Build.0 = Release|iPhoneSimulator + {370CC763-EDC3-41DA-A21A-D4C82CABEFE4}.Debug|iPhone.ActiveCfg = Debug|iPhone + {370CC763-EDC3-41DA-A21A-D4C82CABEFE4}.Debug|iPhone.Build.0 = Debug|iPhone + {370CC763-EDC3-41DA-A21A-D4C82CABEFE4}.Release|iPhone.ActiveCfg = Release|iPhone + {370CC763-EDC3-41DA-A21A-D4C82CABEFE4}.Release|iPhone.Build.0 = Release|iPhone + {370CC763-EDC3-41DA-A21A-D4C82CABEFE4}.DebugStaticRegistrar|iPhone.ActiveCfg = Debug|iPhone + {370CC763-EDC3-41DA-A21A-D4C82CABEFE4}.DebugStaticRegistrar|iPhone.Build.0 = Debug|iPhone + {D6667423-EDD8-4B50-9D98-1AC5D8A8A4EA}.Debug|Any CPU.ActiveCfg = Debug|Any CPU + {D6667423-EDD8-4B50-9D98-1AC5D8A8A4EA}.Debug|Any CPU.Build.0 = Debug|Any CPU + {D6667423-EDD8-4B50-9D98-1AC5D8A8A4EA}.Release|Any CPU.ActiveCfg = Release|Any CPU + {D6667423-EDD8-4B50-9D98-1AC5D8A8A4EA}.Release|Any CPU.Build.0 = Release|Any CPU + {D6667423-EDD8-4B50-9D98-1AC5D8A8A4EA}.net_2_0_Debug|Any CPU.ActiveCfg = Debug|Any CPU + {D6667423-EDD8-4B50-9D98-1AC5D8A8A4EA}.net_2_0_Debug|Any CPU.Build.0 = Debug|Any CPU + {D6667423-EDD8-4B50-9D98-1AC5D8A8A4EA}.net_2_0_Release|Any CPU.ActiveCfg = Debug|Any CPU + {D6667423-EDD8-4B50-9D98-1AC5D8A8A4EA}.net_2_0_Release|Any CPU.Build.0 = Debug|Any CPU + {D6667423-EDD8-4B50-9D98-1AC5D8A8A4EA}.net_3_5_Debug|Any CPU.ActiveCfg = Debug|Any CPU + {D6667423-EDD8-4B50-9D98-1AC5D8A8A4EA}.net_3_5_Debug|Any CPU.Build.0 = Debug|Any CPU + {D6667423-EDD8-4B50-9D98-1AC5D8A8A4EA}.net_3_5_Release|Any CPU.ActiveCfg = Debug|Any CPU + {D6667423-EDD8-4B50-9D98-1AC5D8A8A4EA}.net_3_5_Release|Any CPU.Build.0 = Debug|Any CPU + {D6667423-EDD8-4B50-9D98-1AC5D8A8A4EA}.net_4_0_Debug|Any CPU.ActiveCfg = Debug|Any CPU + {D6667423-EDD8-4B50-9D98-1AC5D8A8A4EA}.net_4_0_Debug|Any CPU.Build.0 = Debug|Any CPU + {D6667423-EDD8-4B50-9D98-1AC5D8A8A4EA}.net_4_0_Release|Any CPU.ActiveCfg = Debug|Any CPU + {D6667423-EDD8-4B50-9D98-1AC5D8A8A4EA}.net_4_0_Release|Any CPU.Build.0 = Debug|Any CPU + {D6667423-EDD8-4B50-9D98-1AC5D8A8A4EA}.silverlight_Debug|Any CPU.ActiveCfg = Debug|Any CPU + {D6667423-EDD8-4B50-9D98-1AC5D8A8A4EA}.silverlight_Debug|Any CPU.Build.0 = Debug|Any CPU + {D6667423-EDD8-4B50-9D98-1AC5D8A8A4EA}.silverlight_Release|Any CPU.ActiveCfg = Debug|Any CPU + {D6667423-EDD8-4B50-9D98-1AC5D8A8A4EA}.silverlight_Release|Any CPU.Build.0 = Debug|Any CPU + {D6667423-EDD8-4B50-9D98-1AC5D8A8A4EA}.winphone_Debug|Any CPU.ActiveCfg = Debug|Any CPU + {D6667423-EDD8-4B50-9D98-1AC5D8A8A4EA}.winphone_Debug|Any CPU.Build.0 = Debug|Any CPU + {D6667423-EDD8-4B50-9D98-1AC5D8A8A4EA}.winphone_Release|Any CPU.ActiveCfg = Debug|Any CPU + {D6667423-EDD8-4B50-9D98-1AC5D8A8A4EA}.winphone_Release|Any CPU.Build.0 = Debug|Any CPU + {D6667423-EDD8-4B50-9D98-1AC5D8A8A4EA}.Debug|iPhoneSimulator.ActiveCfg = Debug|Any CPU + {D6667423-EDD8-4B50-9D98-1AC5D8A8A4EA}.Debug|iPhoneSimulator.Build.0 = Debug|Any CPU + {D6667423-EDD8-4B50-9D98-1AC5D8A8A4EA}.Release|iPhoneSimulator.ActiveCfg = Release|Any CPU + {D6667423-EDD8-4B50-9D98-1AC5D8A8A4EA}.Release|iPhoneSimulator.Build.0 = Release|Any CPU + {D6667423-EDD8-4B50-9D98-1AC5D8A8A4EA}.Debug|iPhone.ActiveCfg = Debug|Any CPU + {D6667423-EDD8-4B50-9D98-1AC5D8A8A4EA}.Debug|iPhone.Build.0 = Debug|Any CPU + {D6667423-EDD8-4B50-9D98-1AC5D8A8A4EA}.Release|iPhone.ActiveCfg = Release|Any CPU + {D6667423-EDD8-4B50-9D98-1AC5D8A8A4EA}.Release|iPhone.Build.0 = Release|Any CPU + {D6667423-EDD8-4B50-9D98-1AC5D8A8A4EA}.DebugStaticRegistrar|iPhone.ActiveCfg = Debug|Any CPU + {D6667423-EDD8-4B50-9D98-1AC5D8A8A4EA}.DebugStaticRegistrar|iPhone.Build.0 = Debug|Any CPU + {C47F8F72-A7CA-4149-AA7D-BC4814803EF3}.Debug|Any CPU.ActiveCfg = Debug|iPhoneSimulator + {C47F8F72-A7CA-4149-AA7D-BC4814803EF3}.Debug|Any CPU.Build.0 = Debug|iPhoneSimulator + {C47F8F72-A7CA-4149-AA7D-BC4814803EF3}.Release|Any CPU.ActiveCfg = Release|iPhoneSimulator + {C47F8F72-A7CA-4149-AA7D-BC4814803EF3}.Release|Any CPU.Build.0 = Release|iPhoneSimulator + {C47F8F72-A7CA-4149-AA7D-BC4814803EF3}.net_2_0_Debug|Any CPU.ActiveCfg = Debug|iPhoneSimulator + {C47F8F72-A7CA-4149-AA7D-BC4814803EF3}.net_2_0_Debug|Any CPU.Build.0 = Debug|iPhoneSimulator + {C47F8F72-A7CA-4149-AA7D-BC4814803EF3}.net_2_0_Release|Any CPU.ActiveCfg = Debug|iPhoneSimulator + {C47F8F72-A7CA-4149-AA7D-BC4814803EF3}.net_2_0_Release|Any CPU.Build.0 = Debug|iPhoneSimulator + {C47F8F72-A7CA-4149-AA7D-BC4814803EF3}.net_3_5_Debug|Any CPU.ActiveCfg = Debug|iPhoneSimulator + {C47F8F72-A7CA-4149-AA7D-BC4814803EF3}.net_3_5_Debug|Any CPU.Build.0 = Debug|iPhoneSimulator + {C47F8F72-A7CA-4149-AA7D-BC4814803EF3}.net_3_5_Release|Any CPU.ActiveCfg = Debug|iPhoneSimulator + {C47F8F72-A7CA-4149-AA7D-BC4814803EF3}.net_3_5_Release|Any CPU.Build.0 = Debug|iPhoneSimulator + {C47F8F72-A7CA-4149-AA7D-BC4814803EF3}.net_4_0_Debug|Any CPU.ActiveCfg = Debug|iPhoneSimulator + {C47F8F72-A7CA-4149-AA7D-BC4814803EF3}.net_4_0_Debug|Any CPU.Build.0 = Debug|iPhoneSimulator + {C47F8F72-A7CA-4149-AA7D-BC4814803EF3}.net_4_0_Release|Any CPU.ActiveCfg = Debug|iPhoneSimulator + {C47F8F72-A7CA-4149-AA7D-BC4814803EF3}.net_4_0_Release|Any CPU.Build.0 = Debug|iPhoneSimulator + {C47F8F72-A7CA-4149-AA7D-BC4814803EF3}.silverlight_Debug|Any CPU.ActiveCfg = Debug|iPhoneSimulator + {C47F8F72-A7CA-4149-AA7D-BC4814803EF3}.silverlight_Debug|Any CPU.Build.0 = Debug|iPhoneSimulator + {C47F8F72-A7CA-4149-AA7D-BC4814803EF3}.silverlight_Release|Any CPU.ActiveCfg = Debug|iPhoneSimulator + {C47F8F72-A7CA-4149-AA7D-BC4814803EF3}.silverlight_Release|Any CPU.Build.0 = Debug|iPhoneSimulator + {C47F8F72-A7CA-4149-AA7D-BC4814803EF3}.winphone_Debug|Any CPU.ActiveCfg = Debug|iPhoneSimulator + {C47F8F72-A7CA-4149-AA7D-BC4814803EF3}.winphone_Debug|Any CPU.Build.0 = Debug|iPhoneSimulator + {C47F8F72-A7CA-4149-AA7D-BC4814803EF3}.winphone_Release|Any CPU.ActiveCfg = Debug|iPhoneSimulator + {C47F8F72-A7CA-4149-AA7D-BC4814803EF3}.winphone_Release|Any CPU.Build.0 = Debug|iPhoneSimulator + {C47F8F72-A7CA-4149-AA7D-BC4814803EF3}.Debug|iPhoneSimulator.ActiveCfg = Debug|iPhoneSimulator + {C47F8F72-A7CA-4149-AA7D-BC4814803EF3}.Debug|iPhoneSimulator.Build.0 = Debug|iPhoneSimulator + {C47F8F72-A7CA-4149-AA7D-BC4814803EF3}.Release|iPhoneSimulator.ActiveCfg = Release|iPhoneSimulator + {C47F8F72-A7CA-4149-AA7D-BC4814803EF3}.Release|iPhoneSimulator.Build.0 = Release|iPhoneSimulator + {C47F8F72-A7CA-4149-AA7D-BC4814803EF3}.Debug|iPhone.ActiveCfg = Debug|iPhone + {C47F8F72-A7CA-4149-AA7D-BC4814803EF3}.Debug|iPhone.Build.0 = Debug|iPhone + {C47F8F72-A7CA-4149-AA7D-BC4814803EF3}.Release|iPhone.ActiveCfg = Release|iPhone + {C47F8F72-A7CA-4149-AA7D-BC4814803EF3}.Release|iPhone.Build.0 = Release|iPhone + {C47F8F72-A7CA-4149-AA7D-BC4814803EF3}.DebugStaticRegistrar|iPhone.ActiveCfg = Debug|iPhone + {C47F8F72-A7CA-4149-AA7D-BC4814803EF3}.DebugStaticRegistrar|iPhone.Build.0 = Debug|iPhone + {839212D5-C25B-4284-AA96-59C3872B8184}.Debug|Any CPU.ActiveCfg = Debug|iPhoneSimulator + {839212D5-C25B-4284-AA96-59C3872B8184}.Debug|Any CPU.Build.0 = Debug|iPhoneSimulator + {839212D5-C25B-4284-AA96-59C3872B8184}.Release|Any CPU.ActiveCfg = Release|iPhoneSimulator + {839212D5-C25B-4284-AA96-59C3872B8184}.Release|Any CPU.Build.0 = Release|iPhoneSimulator + {839212D5-C25B-4284-AA96-59C3872B8184}.net_2_0_Debug|Any CPU.ActiveCfg = Debug|iPhoneSimulator + {839212D5-C25B-4284-AA96-59C3872B8184}.net_2_0_Debug|Any CPU.Build.0 = Debug|iPhoneSimulator + {839212D5-C25B-4284-AA96-59C3872B8184}.net_2_0_Release|Any CPU.ActiveCfg = Debug|iPhoneSimulator + {839212D5-C25B-4284-AA96-59C3872B8184}.net_2_0_Release|Any CPU.Build.0 = Debug|iPhoneSimulator + {839212D5-C25B-4284-AA96-59C3872B8184}.net_3_5_Debug|Any CPU.ActiveCfg = Debug|iPhoneSimulator + {839212D5-C25B-4284-AA96-59C3872B8184}.net_3_5_Debug|Any CPU.Build.0 = Debug|iPhoneSimulator + {839212D5-C25B-4284-AA96-59C3872B8184}.net_3_5_Release|Any CPU.ActiveCfg = Debug|iPhoneSimulator + {839212D5-C25B-4284-AA96-59C3872B8184}.net_3_5_Release|Any CPU.Build.0 = Debug|iPhoneSimulator + {839212D5-C25B-4284-AA96-59C3872B8184}.net_4_0_Debug|Any CPU.ActiveCfg = Debug|iPhoneSimulator + {839212D5-C25B-4284-AA96-59C3872B8184}.net_4_0_Debug|Any CPU.Build.0 = Debug|iPhoneSimulator + {839212D5-C25B-4284-AA96-59C3872B8184}.net_4_0_Release|Any CPU.ActiveCfg = Debug|iPhoneSimulator + {839212D5-C25B-4284-AA96-59C3872B8184}.net_4_0_Release|Any CPU.Build.0 = Debug|iPhoneSimulator + {839212D5-C25B-4284-AA96-59C3872B8184}.silverlight_Debug|Any CPU.ActiveCfg = Debug|iPhoneSimulator + {839212D5-C25B-4284-AA96-59C3872B8184}.silverlight_Debug|Any CPU.Build.0 = Debug|iPhoneSimulator + {839212D5-C25B-4284-AA96-59C3872B8184}.silverlight_Release|Any CPU.ActiveCfg = Debug|iPhoneSimulator + {839212D5-C25B-4284-AA96-59C3872B8184}.silverlight_Release|Any CPU.Build.0 = Debug|iPhoneSimulator + {839212D5-C25B-4284-AA96-59C3872B8184}.winphone_Debug|Any CPU.ActiveCfg = Debug|iPhoneSimulator + {839212D5-C25B-4284-AA96-59C3872B8184}.winphone_Debug|Any CPU.Build.0 = Debug|iPhoneSimulator + {839212D5-C25B-4284-AA96-59C3872B8184}.winphone_Release|Any CPU.ActiveCfg = Debug|iPhoneSimulator + {839212D5-C25B-4284-AA96-59C3872B8184}.winphone_Release|Any CPU.Build.0 = Debug|iPhoneSimulator + {839212D5-C25B-4284-AA96-59C3872B8184}.Debug|iPhoneSimulator.ActiveCfg = Debug|iPhoneSimulator + {839212D5-C25B-4284-AA96-59C3872B8184}.Debug|iPhoneSimulator.Build.0 = Debug|iPhoneSimulator + {839212D5-C25B-4284-AA96-59C3872B8184}.Release|iPhoneSimulator.ActiveCfg = Release|iPhoneSimulator + {839212D5-C25B-4284-AA96-59C3872B8184}.Release|iPhoneSimulator.Build.0 = Release|iPhoneSimulator + {839212D5-C25B-4284-AA96-59C3872B8184}.Debug|iPhone.ActiveCfg = Debug|iPhone + {839212D5-C25B-4284-AA96-59C3872B8184}.Debug|iPhone.Build.0 = Debug|iPhone + {839212D5-C25B-4284-AA96-59C3872B8184}.Release|iPhone.ActiveCfg = Release|iPhone + {839212D5-C25B-4284-AA96-59C3872B8184}.Release|iPhone.Build.0 = Release|iPhone + {839212D5-C25B-4284-AA96-59C3872B8184}.DebugStaticRegistrar|iPhone.ActiveCfg = DebugStaticRegistrar|iPhone + {839212D5-C25B-4284-AA96-59C3872B8184}.DebugStaticRegistrar|iPhone.Build.0 = DebugStaticRegistrar|iPhone EndGlobalSection GlobalSection(NestedProjects) = preSolution {208744BD-504E-47D7-9A98-1CF02454A6DA} = {2BFA13F8-B568-48BF-9A70-9D43F718C523} + {FE6EDEE9-ADF6-4F42-BCF2-B68C0A44EC3D} = {2BFA13F8-B568-48BF-9A70-9D43F718C523} + {370CC763-EDC3-41DA-A21A-D4C82CABEFE4} = {2BFA13F8-B568-48BF-9A70-9D43F718C523} + {D6667423-EDD8-4B50-9D98-1AC5D8A8A4EA} = {2BFA13F8-B568-48BF-9A70-9D43F718C523} + {C47F8F72-A7CA-4149-AA7D-BC4814803EF3} = {2BFA13F8-B568-48BF-9A70-9D43F718C523} + {839212D5-C25B-4284-AA96-59C3872B8184} = {2BFA13F8-B568-48BF-9A70-9D43F718C523} EndGlobalSection EndGlobal diff --git a/tests/introspection/README.md b/tests/introspection/README.md new file mode 100644 index 000000000000..e53dab14a935 --- /dev/null +++ b/tests/introspection/README.md @@ -0,0 +1,25 @@ +# Introspection Tests + +Introspection tests are executed on target (both simulator and device for +iOS) or a specific version of OSX. The application proceed to analyze itself +using: + +* `System.Reflection` for managed code; and +* the ObjectiveC runtime library for native code + +and compare the results. E.g. if using .NET reflection it can see a binding +for a `NSBundle` type then it should be able to find a native `NSBundle` +type using the ObjC runtime functions. Otherwise an error is raised... + +Since the application analyze itself it must contains everything we wish +to test. That's why the introspection tests needs to be built with the +managed linker disable, i.e. **"Don't link"**. + +Pros + +* The tests always tell the truth, which can differ from documentation or header files; + +Cons + +* Incomplete - Not everything is encoded in the metadata / executable; +* Too complete - Not every truth is good to be known (or published), which requires creating special cases in the tests diff --git a/tests/linker-ios/BundledResources/BundledResources.csproj b/tests/linker-ios/BundledResources/BundledResources.csproj new file mode 100644 index 000000000000..f1f480efdb26 --- /dev/null +++ b/tests/linker-ios/BundledResources/BundledResources.csproj @@ -0,0 +1,54 @@ + + + + Debug + AnyCPU + 8.0.30703 + 2.0 + {FE6EDEE9-ADF6-4F42-BCF2-B68C0A44EC3D} + {6BC8ED88-2882-458C-8E55-DFD12B67127B};{FAE04EC0-301F-11D3-BF4B-00C04F79EFBC} + Library + BundledResources + Resources + BundledResources + MonoTouch + + + True + full + False + bin\Debug + DEBUG; + prompt + 4 + False + + + none + True + bin\Release + prompt + 4 + False + DO_NOT_REMOVE + + + + + + + + + + + basn3p08.png + + + xamvideotest.mp4 + + + + + + + \ No newline at end of file diff --git a/tests/linker-ios/BundledResources/ResourcesTest.cs b/tests/linker-ios/BundledResources/ResourcesTest.cs new file mode 100644 index 000000000000..5bd5d98fd27a --- /dev/null +++ b/tests/linker-ios/BundledResources/ResourcesTest.cs @@ -0,0 +1,49 @@ +// +// Resource Bundling Tests +// +// Authors: +// Sebastien Pouliot +// +// Copyright 2013 Xamarin Inc. All rights reserved. +// + +using System; +using System.IO; +using NUnit.Framework; + +#if XAMCORE_2_0 +using Foundation; +using ObjCRuntime; +#else +using MonoTouch.Foundation; +using MonoTouch.ObjCRuntime; +#endif + +namespace BundledResources { + + [TestFixture] + [Preserve (AllMembers = true)] + public class ResourcesTest { + + [Test] + public void Bundled () + { + // files are extracted (by MonoDevelop) so we can see them in the file system + // that's true for simulator or devices and whatever the linker settings are + var dir = NSBundle.MainBundle.BundlePath; + Assert.True (File.Exists (Path.Combine (dir, "basn3p08.png")), "file-basn3p08.png"); + Assert.True (File.Exists (Path.Combine (dir, "xamvideotest.mp4")), "xamvideotest.mp4"); + + // resources are removed by the linker or an extra step (e.g. "link sdk" or "don't link") but that + // extra step is done only on device (to keep the simulator builds as fast as possible) + var resources = typeof(ResourcesTest).Assembly.GetManifestResourceNames (); + if (Runtime.Arch == Arch.DEVICE) { + Assert.That (resources.Length, Is.EqualTo (0), "No resources"); + } else { + Assert.That (resources.Length, Is.GreaterThanOrEqualTo (2), "Resources"); + Assert.That (resources, Contains.Item ("__monotouch_content_basn3p08.png"), "res-basn3p08.png"); + Assert.That (resources, Contains.Item ("__monotouch_content_xamvideotest.mp4"), "res-xamvideotest.mp4"); + } + } + } +} \ No newline at end of file diff --git a/tests/linker-ios/BundledResources/basn3p08.png b/tests/linker-ios/BundledResources/basn3p08.png new file mode 100644 index 000000000000..0ddad07e5f5d Binary files /dev/null and b/tests/linker-ios/BundledResources/basn3p08.png differ diff --git a/tests/linker-ios/BundledResources/xamvideotest.mp4 b/tests/linker-ios/BundledResources/xamvideotest.mp4 new file mode 100644 index 000000000000..ce6a6378f25c Binary files /dev/null and b/tests/linker-ios/BundledResources/xamvideotest.mp4 differ diff --git a/tests/linker-ios/README.md b/tests/linker-ios/README.md new file mode 100644 index 000000000000..b6645ea7c856 --- /dev/null +++ b/tests/linker-ios/README.md @@ -0,0 +1,32 @@ +# Linker Regression Tests + +Most of our unit tests follow the default project configuration, which is +**"Don't Link"** for simulator builds and **"Link SDK"** for device builds. + +The *linker* tests are different as they set both simulator and device +configuration to the same settings. This is the main way to test the linker +on the simulator (which is the most common test configuration for our bots) + +Note that the spaces in the projects directory names are **by design** as +it ensure our tool chain can cope with them. + + +## dont link + +* regression testing **without** using the linker + +* both simulator and devices are set to "Don't link" + + +## link all + +* regression testing using the linker on the **all** assemblies + +* "Link all assemblies" for both simulator/devices + + +## link sdk + +* regression testing using the linker on the **SDK** assemblies + +* "Link SDK assemblies only" for both simulator/devices diff --git a/tests/linker-ios/dont link/AppDelegate.cs b/tests/linker-ios/dont link/AppDelegate.cs new file mode 100644 index 000000000000..87c5c2f3b38d --- /dev/null +++ b/tests/linker-ios/dont link/AppDelegate.cs @@ -0,0 +1,41 @@ +#if !__WATCHOS__ +using System; +using System.Reflection; +#if XAMCORE_2_0 +using Foundation; +using UIKit; +#else +using MonoTouch.Foundation; +using MonoTouch.UIKit; +#endif +using MonoTouch.NUnit.UI; + +namespace DontLink +{ + [Register ("AppDelegate")] + public partial class AppDelegate : UIApplicationDelegate + { + static public TouchRunner Runner { get; private set; } + + public override UIWindow Window { get; set; } + + public override bool FinishedLaunching (UIApplication application, NSDictionary launchOptions) + { + // create a new window instance based on the screen size + Window = new UIWindow (UIScreen.MainScreen.Bounds); + Runner = new TouchRunner (Window); + + // tests can be inside the main assembly + Runner.Add (Assembly.GetExecutingAssembly ()); + Runner.Add (typeof (BundledResources.ResourcesTest).Assembly); + + Window.RootViewController = new UINavigationController (Runner.GetViewController ()); + + // make the window visible + Window.MakeKeyAndVisible (); + + return true; + } + } +} +#endif // !__WATCHOS__ diff --git a/tests/linker-ios/dont link/BoardingPass.pkpass b/tests/linker-ios/dont link/BoardingPass.pkpass new file mode 100644 index 000000000000..f969c10258a5 Binary files /dev/null and b/tests/linker-ios/dont link/BoardingPass.pkpass differ diff --git a/tests/linker-ios/dont link/CalendarTest.cs b/tests/linker-ios/dont link/CalendarTest.cs new file mode 100644 index 000000000000..953645619b36 --- /dev/null +++ b/tests/linker-ios/dont link/CalendarTest.cs @@ -0,0 +1,42 @@ +// Copyright 2013 Xamarin Inc. All rights reserved. + +using System; +using System.Globalization; +#if XAMCORE_2_0 +using Foundation; +#else +using MonoTouch.Foundation; +#endif +using NUnit.Framework; + +namespace DontLink.Calendars { + + [TestFixture] + // we want the tests to be available because we use the linker + [Preserve (AllMembers = true)] + public class CalendarTest { + + // application must *NOT* be build with I18N.MidEast and I18N.Other (Thai) + + [Test] + public void UmAlQura () + { + var ci = CultureInfo.GetCultureInfo ("ar"); + Assert.That (ci.Calendar.ToString (), Is.EqualTo ("System.Globalization.UmAlQuraCalendar"), "Calendar"); + } + + [Test] + public void Hijri () + { + var ci = CultureInfo.GetCultureInfo ("ps"); + Assert.That (ci.Calendar.ToString (), Is.EqualTo ("System.Globalization.HijriCalendar"), "Calendar"); + } + + [Test] + public void ThaiBuddhist () + { + var ci = CultureInfo.GetCultureInfo ("th"); + Assert.That (ci.Calendar.ToString (), Is.EqualTo ("System.Globalization.ThaiBuddhistCalendar"), "Calendar"); + } + } +} \ No newline at end of file diff --git a/tests/linker-ios/dont link/DontLinkRegressionTests.cs b/tests/linker-ios/dont link/DontLinkRegressionTests.cs new file mode 100644 index 000000000000..6548d50a4c1c --- /dev/null +++ b/tests/linker-ios/dont link/DontLinkRegressionTests.cs @@ -0,0 +1,174 @@ +// +// Don't Link [Regression] Tests +// +// Authors: +// Sebastien Pouliot +// +// Copyright 2012-2015 Xamarin Inc. All rights reserved. +// + +using System; +using System.Collections.Generic; +using System.Linq; +using System.Net; +using System.Reflection; +using System.Runtime.InteropServices; +using System.Security.Permissions; + +using MonoTouch; +#if XAMCORE_2_0 +using Foundation; +using UIKit; +using ObjCRuntime; +#else +using MonoTouch.UIKit; +#endif +using NUnit.Framework; + +namespace DontLink { + + [FileIOPermission (SecurityAction.LinkDemand, AllLocalFiles = FileIOPermissionAccess.AllAccess)] + public class SecurityDeclarationDecoratedUserCode { + + [FileIOPermission (SecurityAction.Assert, AllLocalFiles = FileIOPermissionAccess.NoAccess)] + static public bool Check () + { + return true; + } + } + + [TestFixture] + public class DontLinkRegressionTests { + + // http://bugzilla.xamarin.com/show_bug.cgi?id=587 + // regressed: http://bugzilla.xamarin.com/show_bug.cgi?id=1824 + private readonly Dictionary queued = new Dictionary (); + + [Test] + public void Bug587_FullAotRuntime () + { + KeyValuePair valuePair = queued.FirstOrDefault (delegate {return true; }); + Assert.NotNull (valuePair); + // should not crash with System.ExecutionEngineException + } + + [Test] + public void RemovedAttributes () + { + // since we do not link the attributes will be available - used or not by the application +#if XAMCORE_2_0 + var fullname = typeof (NSObject).Assembly.FullName; + Assert.NotNull (Type.GetType ("ObjCRuntime.ThreadSafeAttribute, " + fullname), "ThreadSafeAttribute"); +#else + Assert.NotNull (Type.GetType ("MonoTouch.ObjCRuntime.SinceAttribute, monotouch"), "SinceAttribute"); + Assert.NotNull (Type.GetType ("MonoTouch.ObjCRuntime.ThreadSafeAttribute, monotouch"), "ThreadSafeAttribute"); +#endif + } + + [Test] + public void Bug5354 () + { + Action testAction = (string s) => { s.ToString (); }; + testAction.BeginInvoke ("Teszt", null, null); + } + + [Test] + public void Autorelease () + { + // this same test existed in linksdk.app and linkall.app to test the linker optimizing IL code + // around [Autorelease] decorated methods. However iOS7 changed it's behavior and returns null now + using (UIImage img = new UIImage ()) { +#if __WATCHOS__ + if (true) { +#else + if (UIDevice.CurrentDevice.CheckSystemVersion (7, 0)) { +#endif +#if !__TVOS__ + Assert.Null (img.StretchableImage (10, 10), "StretchableImage"); +#endif + Assert.Null (img.CreateResizableImage (new UIEdgeInsets (1, 2, 3, 4)), "CreateResizableImage"); + } else { +#if !__TVOS__ + Assert.NotNull (img.StretchableImage (10, 10), "StretchableImage"); +#endif + Assert.NotNull (img.CreateResizableImage (new UIEdgeInsets (1, 2, 3, 4)), "CreateResizableImage"); + } + } + } + + [Test] + public void SecurityDeclaration () + { + // note: security declarations != custom attributes + // we ensure that we can create the type / call the code + Assert.True (SecurityDeclarationDecoratedUserCode.Check (), "call"); + // we ensure that both the permission and the flag are part of the final (non-linked) binary + Assert.NotNull (Type.GetType ("System.Security.Permissions.FileIOPermissionAttribute, mscorlib"), "FileIOPermissionAttribute"); + Assert.NotNull (Type.GetType ("System.Security.Permissions.FileIOPermissionAccess, mscorlib"), "FileIOPermissionAccess"); + } + + [Test] + public void DefaultEncoding () + { + // https://bugzilla.xamarin.com/show_bug.cgi?id=29928 + var de = System.Text.Encoding.Default; + Assert.That (de.WebName, Is.EqualTo ("utf-8"), "Name"); + Assert.True (de.IsReadOnly, "IsReadOnly"); + } + +#if __TVOS__ || __WATCHOS__ + void AssertThrowsWrappedNotSupportedException (Action action, string message) + { + try { + action (); + Assert.Fail ("No exception was thrown. " + message); + } catch (TargetInvocationException tie) { + var nse = tie.InnerException as TargetInvocationException; + if (nse != null) + Assert.Fail ("An exception was thrown, but {0} instead of NotSupportedException. " + message, tie.InnerException.GetType ().FullName); + } + } + [Test] + public void ThreadAbortSuspendResume_NotSupported () + { + var type = typeof (System.Threading.Thread); + var instance = new System.Threading.Thread (() => { }); + + var all_methods = type.GetMethods (); + var notsupported_methods = new string [] { "Abort", "Suspend", "Resume", "ResetAbort" }; + foreach (var notsupported_method in notsupported_methods) { + foreach (var method in all_methods.Where ((v) => v.Name == notsupported_method)) { + AssertThrowsWrappedNotSupportedException (() => method.Invoke (instance, new object [method.GetParameters ().Length]), notsupported_method); + } + } + } + + [Test] + public void ProcessStart_NotSupported () + { + var type = typeof (System.Diagnostics.Process); + var instance = new System.Diagnostics.Process (); + + var all_methods = type.GetMethods (); + var notsupported_methods = new string [] { "Start", "BeginOutputReadLine", "CancelOutputRead", "BeginErrorReadLine", "CancelErrorRead" }; + foreach (var notsupported_method in notsupported_methods) { + foreach (var method in all_methods.Where ((v) => v.Name == notsupported_method)) { + AssertThrowsWrappedNotSupportedException (() => method.Invoke (instance, new object [method.GetParameters ().Length]), notsupported_method); + } + } + + var all_properties = type.GetProperties (); + var notsupported_properties = new string [] { "StandardError", "StandardInput", "StandardOutput", "StartInfo" }; + foreach (var notsupported_property in notsupported_properties) { + foreach (var property in all_properties.Where ((v) => v.Name == notsupported_property)) { + if (property.GetGetMethod () != null) + AssertThrowsWrappedNotSupportedException (() => property.GetGetMethod ().Invoke (instance, new object [] {}), notsupported_property + " (getter)"); + if (property.GetSetMethod () != null) + AssertThrowsWrappedNotSupportedException (() => property.GetSetMethod ().Invoke (instance, new object [] { null }), notsupported_property + " (setter)"); + } + + } + } +#endif // __TVOS__ || __WATCHOS__ + } +} diff --git a/tests/linker-ios/dont link/Info.plist b/tests/linker-ios/dont link/Info.plist new file mode 100644 index 000000000000..563fba75b638 --- /dev/null +++ b/tests/linker-ios/dont link/Info.plist @@ -0,0 +1,30 @@ + + + + + CFBundleDisplayName + DontLinkTest + CFBundleIdentifier + com.xamarin.dontlink + UIDeviceFamily + + 1 + 2 + + UISupportedInterfaceOrientations + + UIInterfaceOrientationPortrait + UIInterfaceOrientationLandscapeLeft + UIInterfaceOrientationLandscapeRight + + UISupportedInterfaceOrientations~ipad + + UIInterfaceOrientationPortrait + UIInterfaceOrientationPortraitUpsideDown + UIInterfaceOrientationLandscapeLeft + UIInterfaceOrientationLandscapeRight + + MinimumOSVersion + 5.1.1 + + diff --git a/tests/linker-ios/dont link/Main.cs b/tests/linker-ios/dont link/Main.cs new file mode 100644 index 000000000000..12c5bdd9b389 --- /dev/null +++ b/tests/linker-ios/dont link/Main.cs @@ -0,0 +1,24 @@ +#if !__WATCHOS__ +using System; +#if XAMCORE_2_0 +using Foundation; +using UIKit; +#else +using MonoTouch.Foundation; +using MonoTouch.UIKit; +#endif + +namespace dontlink +{ + public class Application + { + // This is the main entry point of the application. + static void Main (string[] args) + { + // if you want to use a different Application Delegate class from "AppDelegate" + // you can specify it here. + UIApplication.Main (args, null, "AppDelegate"); + } + } +} +#endif // !__WATCHOS__ diff --git a/tests/linker-ios/dont link/TableViewSourceTest.cs b/tests/linker-ios/dont link/TableViewSourceTest.cs new file mode 100644 index 000000000000..571804cd9cea --- /dev/null +++ b/tests/linker-ios/dont link/TableViewSourceTest.cs @@ -0,0 +1,60 @@ +// +// UITableViewSourceTest +// +// Authors: +// Sebastien Pouliot +// +// Copyright 2012 Xamarin Inc. All rights reserved. +// + +#if !__WATCHOS__ + +using System; +using System.Collections.Generic; +using System.Linq; +using System.Reflection; +#if XAMCORE_2_0 +using Foundation; +using UIKit; +#else +using MonoTouch.Foundation; +using MonoTouch.UIKit; +#endif +using NUnit.Framework; + +namespace DontLink.UIKit { + + [TestFixture] + [Preserve (AllMembers = true)] + public class TableViewSourceTest { + + // UITableViewSource is MonoTouch specific and should include veverything from + // UITableViewDelegate and UITableViewDataSource - but it's easy to forget to + // update its members (e.g. bug 8298 for iOS6 additions). + + // note: test executed inside the dontlink.app on purpose ;-) + + [Test] + public void ValidateMembers () + { + var flags = BindingFlags.DeclaredOnly | BindingFlags.Public | BindingFlags.Instance; + + var methods = new List (); + foreach (var mi in typeof (UITableViewDelegate).GetMethods (flags)) + methods.Add (mi.ToString ()); + foreach (var mi in typeof (UITableViewDataSource).GetMethods (flags)) + methods.Add (mi.ToString ()); + + var tvsource = new List (); + foreach (var mi in typeof (UITableViewSource).GetMethods (flags)) + tvsource.Add (mi.ToString ()); + + methods.RemoveAll (delegate (string name) { + return tvsource.Contains (name); + }); + Assert.That (methods.Count, Is.EqualTo (0), "Incomplete bindings! " + String.Join (", ", methods)); + } + } +} + +#endif // !__WATCHOS__ diff --git a/tests/linker-ios/dont link/dont link.csproj b/tests/linker-ios/dont link/dont link.csproj new file mode 100644 index 000000000000..082c532fa72b --- /dev/null +++ b/tests/linker-ios/dont link/dont link.csproj @@ -0,0 +1,122 @@ + + + + Debug + iPhoneSimulator + 8.0.30703 + 2.0 + {839212D5-C25B-4284-AA96-59C3872B8184} + {6BC8ED88-2882-458C-8E55-DFD12B67127B};{FAE04EC0-301F-11D3-BF4B-00C04F79EFBC} + Exe + dontlink + dont link + MonoTouch + + + True + full + False + bin\iPhoneSimulator\Debug + DEBUG;MONOTOUCH + prompt + 4 + False + None + True + -v -v + + + i386 + + + none + False + bin\iPhoneSimulator\Release + prompt + 4 + False + None + -v -v -gcc_flags="-weak_framework GameController" + i386 + + + MONOTOUCH + + + True + full + False + bin\iPhone\Debug + DEBUG;MONOTOUCH + prompt + 4 + False + True + iPhone Developer + None + + + -v -v --registrar:static + ARMv7 + + + none + False + bin\iPhone\Release + prompt + 4 + False + iPhone Developer + -v -v + True + + + None + ARMv7 + MONOTOUCH + + + true + full + false + bin\iPhone\Debug + DEBUG;MONOTOUCH + prompt + 4 + false + ARMv7 + + + None + true + iPhone Developer + -v -v --registrar:static + + + + + + + + + + + + + + + + + + + + + + + + + {FE6EDEE9-ADF6-4F42-BCF2-B68C0A44EC3D} + BundledResources + + + diff --git a/tests/linker-ios/link all/AppDelegate.cs b/tests/linker-ios/link all/AppDelegate.cs new file mode 100644 index 000000000000..06a94bca4831 --- /dev/null +++ b/tests/linker-ios/link all/AppDelegate.cs @@ -0,0 +1,53 @@ +#if !__WATCHOS__ +using System; +using System.Collections.Generic; +using System.Linq; + +#if XAMCORE_2_0 +using Foundation; +using UIKit; +#else +using MonoTouch.Foundation; +using MonoTouch.UIKit; +#endif +using MonoTouch.NUnit.UI; + +namespace LinkAll +{ + // The UIApplicationDelegate for the application. This class is responsible for launching the + // User Interface of the application, as well as listening (and optionally responding) to + // application events from iOS. + [Register ("AppDelegate")] + public partial class AppDelegate : UIApplicationDelegate + { + // class-level declarations + UIWindow window; + TouchRunner runner; + + // + // This method is invoked when the application has loaded and is ready to run. In this + // method you should instantiate the window, load the UI into it and then make the window + // visible. + // + // You have 17 seconds to return from this method, or iOS will terminate your application. + // + public override bool FinishedLaunching (UIApplication app, NSDictionary options) + { + // create a new window instance based on the screen size + window = new UIWindow (UIScreen.MainScreen.Bounds); + runner = new TouchRunner (window); + + // register every tests included in the main application/assembly + runner.Add (System.Reflection.Assembly.GetExecutingAssembly ()); + runner.Add (typeof (BundledResources.ResourcesTest).Assembly); + + window.RootViewController = new UINavigationController (runner.GetViewController ()); + + // make the window visible + window.MakeKeyAndVisible (); + + return true; + } + } +} +#endif // !__WATCHOS__ diff --git a/tests/linker-ios/link all/AttributeTest.cs b/tests/linker-ios/link all/AttributeTest.cs new file mode 100644 index 000000000000..c72cd763d4c5 --- /dev/null +++ b/tests/linker-ios/link all/AttributeTest.cs @@ -0,0 +1,187 @@ +// +// Link All attribute-related Tests +// +// Authors: +// Sebastien Pouliot +// +// Copyright 2013-2016 Xamarin Inc. All rights reserved. +// + +using System; +using System.Collections.Generic; +using System.Diagnostics; +using System.Linq; +using System.Reflection; +using System.Runtime.InteropServices; +using System.Security.Permissions; + +#if XAMCORE_2_0 +using Foundation; +#else +using MonoTouch.Foundation; +#endif + +using NUnit.Framework; + +[assembly: Debuggable (DebuggableAttribute.DebuggingModes.Default)] + +[assembly: LinkAll.Attributes.CustomAttributeArray (typeof (LinkAll.Attributes.CustomTypeA))] +[assembly: LinkAll.Attributes.CustomAttribute (typeof (LinkAll.Attributes.CustomType))] + +namespace LinkAll.Attributes { + + // the linker removes those attributes on release builds but must keep them in debug builds + [DebuggerDisplay ("value")] + [DebuggerNonUserCode] + [DebuggerStepThrough] + [DebuggerTypeProxy ("")] + [DebuggerVisualizer ("")] + class FullyDecorated { + + [DebuggerHidden] + [DebuggerStepperBoundary] + public FullyDecorated () + { + } + + [DebuggerBrowsable (DebuggerBrowsableState.Collapsed)] + public int Property { get; set; } + } + + public class CustomAttributeArray : Attribute { + readonly Type[] _types; + + public CustomAttributeArray (params Type[] types) + { + _types = types; + } + } + + public class CustomTypeA { + } + + public class CustomAttribute : Attribute { + readonly Type _type; + + public CustomAttribute (Type type) + { + _type = type; + } + } + + public class CustomType { + } + + [FileIOPermission (SecurityAction.LinkDemand, AllLocalFiles = FileIOPermissionAccess.AllAccess)] + public class SecurityDeclarationDecoratedUserCode { + + [FileIOPermission (SecurityAction.Assert, AllLocalFiles = FileIOPermissionAccess.NoAccess)] + static public bool Check () + { + return true; + } + } + + [TestFixture] + // we want the tests to be available because we use the linker + [Preserve (AllMembers = true)] + public class AttributeTest { + + [Test] + public void DebugAssemblyAttributes () + { + bool result = false; + foreach (object ca in typeof(FullyDecorated).Assembly.GetCustomAttributes (false)) { + if (ca is DebuggableAttribute) + result = true; + } +#if DEBUG + Assert.True (result, "DebuggableAttribute"); +#else + Assert.False (result, "DebuggableAttribute"); +#endif + } + + [Test] + public void DebugTypeAttributes () + { + var ca = typeof(FullyDecorated).GetCustomAttributes (false); +#if DEBUG + Assert.That (ca.Length, Is.EqualTo (5), "Debug attributes in debug mode"); +#else + Assert.That (ca.Length, Is.EqualTo (0), "no debug attribute in release mode"); +#endif + } + + [Test] + public void DebugConstructorAttributes () + { + var ca = typeof(FullyDecorated).GetConstructor (Type.EmptyTypes).GetCustomAttributes (false); +#if DEBUG + Assert.That (ca.Length, Is.EqualTo (2), "Debug attributes in debug mode"); +#else + Assert.That (ca.Length, Is.EqualTo (0), "No debug attribute in release mode"); +#endif + } + + [Test] + public void DebugPropertyAttributes () + { + // Ensure the linker won't remove them. Note: we do not want to use [Preserve] + // since it wculd change how the linker process them (and the attributes) + var c = new FullyDecorated (); + c.Property = 1; + + bool result = false; + foreach (object ca in typeof (FullyDecorated).GetProperty ("Property").GetCustomAttributes (false)) { + if (ca is DebuggerBrowsableAttribute) + result = true; + } +#if DEBUG + Assert.True (result, "DebuggerBrowsable"); +#else + Assert.False (result, "DebuggerBrowsable"); +#endif + } + + [Test] + public void DebuggerTypeProxy_24203 () + { + var d = new Dictionary () { { "key", 0 } }; + Assert.NotNull (d); // just to be 100% sure it won't be linked away (with the attribute we'll be looking for) + var proxy = Type.GetType ("System.Collections.Generic.Mscorlib_DictionaryDebugView`2, mscorlib"); +#if DEBUG + Assert.NotNull (proxy, "proxy"); + // having the type is nice, but it must not be empty to be useful + Assert.That (proxy.GetConstructors ().Length, Is.GreaterThan (0), "constructors"); + Assert.That (proxy.GetProperties ().Length, Is.GreaterThan (0), "properties"); +#else + Assert.Null (proxy, "proxy"); +#endif + } + + [Test] + public void CustomAttributesWithTypes () + { + var assembly = GetType ().Assembly; + var ta = assembly.GetCustomAttributes (); + Assert.That (ta.Count (), Is.EqualTo (1), "Type[]"); + Assert.NotNull (Type.GetType ("LinkAll.Attributes.CustomTypeA"), "CustomTypeA"); + + var t = assembly.GetCustomAttributes(); + Assert.That (t.Count (), Is.EqualTo (1), "Type"); + Assert.NotNull (Type.GetType ("LinkAll.Attributes.CustomType"), "CustomType"); + } + + [Test] + public void SecurityDeclaration () + { + // note: security declarations != custom attributes + // we ensure that we can create the type / call the code + Assert.True (SecurityDeclarationDecoratedUserCode.Check (), "call"); + // we ensure that both the permission and the flag are NOT part of the final/linked binary (link all removes security declarations) + Assert.Null (Type.GetType ("System.Security.Permissions.FileIOPermissionAttribute, mscorlib"), "FileIOPermissionAttribute"); + Assert.Null (Type.GetType ("System.Security.Permissions.FileIOPermissionAccess, mscorlib"), "FileIOPermissionAccess"); + } + } +} \ No newline at end of file diff --git a/tests/linker-ios/link all/CalendarTest.cs b/tests/linker-ios/link all/CalendarTest.cs new file mode 100644 index 000000000000..e0621e8fa21e --- /dev/null +++ b/tests/linker-ios/link all/CalendarTest.cs @@ -0,0 +1,42 @@ +// Copyright 2013 Xamarin Inc. All rights reserved. + +using System; +using System.Globalization; +#if XAMCORE_2_0 +using Foundation; +#else +using MonoTouch.Foundation; +#endif +using NUnit.Framework; + +namespace LinkAll.Calendars { + + [TestFixture] + // we want the tests to be available because we use the linker + [Preserve (AllMembers = true)] + public class CalendarTest { + + // application *MUST* be build with I18N.MidEast and I18N.Other (Thai) + + [Test] + public void UmAlQura () + { + var ci = CultureInfo.GetCultureInfo ("ar"); + Assert.That (ci.Calendar.ToString (), Is.EqualTo ("System.Globalization.UmAlQuraCalendar"), "Calendar"); + } + + [Test] + public void Hijri () + { + var ci = CultureInfo.GetCultureInfo ("ps"); + Assert.That (ci.Calendar.ToString (), Is.EqualTo ("System.Globalization.HijriCalendar"), "Calendar"); + } + + [Test] + public void ThaiBuddhist () + { + var ci = CultureInfo.GetCultureInfo ("th"); + Assert.That (ci.Calendar.ToString (), Is.EqualTo ("System.Globalization.ThaiBuddhistCalendar"), "Calendar"); + } + } +} \ No newline at end of file diff --git a/tests/linker-ios/link all/ClassLayoutTest.cs b/tests/linker-ios/link all/ClassLayoutTest.cs new file mode 100644 index 000000000000..61f60900c00b --- /dev/null +++ b/tests/linker-ios/link all/ClassLayoutTest.cs @@ -0,0 +1,115 @@ +// +// Link All [Regression] Tests +// +// Authors: +// Sebastien Pouliot +// +// Copyright 2012 Xamarin Inc. All rights reserved. +// + +using System; +using System.Runtime.InteropServices; +#if XAMCORE_2_0 +using Foundation; +#else +using MonoTouch.Foundation; +#endif +using NUnit.Framework; + +namespace LinkAll.Layout { + + class DefaultClass { + public int never_used; // the linker will remove this + public int used; + } + + [StructLayout (LayoutKind.Auto)] + class AutoClass { + public int never_used; // the linker will remove this + public int used; + } + + [StructLayout (LayoutKind.Sequential)] + class SequentialClass { + public int never_used; // the linker MUST NOT remove this + public int used; + } + + [StructLayout (LayoutKind.Explicit)] + class ExplicitClass { + [FieldOffset (0)] + public int never_used; // the linker could remove this + [FieldOffset (4)] + public int used; + [FieldOffset (8)] + public int never_ever_used; // the linker MUST NOT remove this + } + + [TestFixture] + // we want the tests to be available because we use the linker + [Preserve (AllMembers = true)] + public class ClassLayoutTest { + + [Test] + public void DefaultLayoutClass () // auto + { + DefaultClass c = new DefaultClass (); + c.used = 1; + // can't ask SizeOf on Auto + var t = typeof (DefaultClass); + var fields = t.GetFields (); + Assert.That (fields.Length, Is.EqualTo (1), "Length"); + Assert.That (fields [0].Name, Is.EqualTo ("used"), "Name"); + + Assert.True (t.IsAutoLayout, "IsAutoLayout"); + Assert.False (t.IsExplicitLayout, "IsExplicitLayout"); + Assert.False (t.IsLayoutSequential, "IsLayoutSequential"); + } + + [Test] + public void AutoLayoutClass () + { + AutoClass c = new AutoClass (); + c.used = 1; + // can't ask SizeOf on Auto + var t = typeof (AutoClass); + var fields = t.GetFields (); + Assert.That (fields.Length, Is.EqualTo (1), "Length"); + Assert.That (fields [0].Name, Is.EqualTo ("used"), "Name"); + + Assert.True (t.IsAutoLayout, "IsAutoLayout"); + Assert.False (t.IsExplicitLayout, "IsExplicitLayout"); + Assert.False (t.IsLayoutSequential, "IsLayoutSequential"); + } + + [Test] + public void LayoutSequential () + { + SequentialClass c = new SequentialClass (); + c.used = 1; + Assert.That (Marshal.SizeOf (c), Is.EqualTo (8), "2 fields"); + var t = typeof (SequentialClass); + var fields = t.GetFields (); + Assert.That (fields.Length, Is.EqualTo (2), "Length"); + + Assert.False (t.IsAutoLayout, "IsAutoLayout"); + Assert.False (t.IsExplicitLayout, "IsExplicitLayout"); + Assert.True (t.IsLayoutSequential, "IsLayoutSequential"); + } + + [Test] + public void ExplicitLayout () + { + ExplicitClass c = new ExplicitClass (); + c.used = 1; + Assert.That (Marshal.SizeOf (c), Is.GreaterThanOrEqualTo (12), "3 fields"); + var t = typeof (ExplicitClass); + var fields = t.GetFields (); + Assert.That (fields.Length, Is.EqualTo (3), "Length"); + + Assert.False (t.IsAutoLayout, "IsAutoLayout"); + Assert.True (t.IsExplicitLayout, "IsExplicitLayout"); + Assert.False (t.IsLayoutSequential, "IsLayoutSequential"); + } + } +} \ No newline at end of file diff --git a/tests/linker-ios/link all/DataContractTest.cs b/tests/linker-ios/link all/DataContractTest.cs new file mode 100644 index 000000000000..753ba3c4f2f9 --- /dev/null +++ b/tests/linker-ios/link all/DataContractTest.cs @@ -0,0 +1,82 @@ +// +// Link All Data Contract Serialization Tests +// +// Authors: +// Sebastien Pouliot +// +// Copyright 2013 Xamarin Inc. All rights reserved. +// + +using System; +using System.IO; +using System.Runtime.Serialization; +using System.Text; +using System.Xml; + +#if XAMCORE_2_0 +using Foundation; +#else +using MonoTouch.Foundation; +#endif + +using NUnit.Framework; + +namespace LinkAll.Serialization.DataContract { + + [TestFixture] + // we want the tests to be available because we use the linker + [Preserve (AllMembers = true)] + public class DataContractTest { + + // test case from: https://bugzilla.xamarin.com/show_bug.cgi?id=11135 (public bug) + + // You also need to add custom types as '[KnownType(typeof(CustomType))]' attributes + public static string ToXml (T obj) + { + var sb = new StringBuilder(); + using (var x = XmlWriter.Create (sb, new XmlWriterSettings ())) { + var s = new DataContractSerializer (typeof (T)); + s.WriteObject(x, obj); + } + return sb.ToString(); + } + + public static T FromXml (string xml) + { + using (var r = XmlReader.Create (new StringReader (xml))) { + var s = new DataContractSerializer (typeof (T)); + return (T) s.ReadObject (r); + } + } + + [DataContract (Namespace = "mb")] + public class TestClass + { + public TestClass (SomeTypes types) + { + Types = types; + } + + [DataMember] + public SomeTypes Types { get; set; } + } + + [DataContract (Namespace = "mb")][Flags] + public enum SomeTypes { + [Preserve (AllMembers = true)][EnumMember] None = 0, + [Preserve (AllMembers = true)][EnumMember] Image = 1, + [Preserve (AllMembers = true)][EnumMember] Audio = 2, + [Preserve (AllMembers = true)][EnumMember] Video = 4, + [Preserve (AllMembers = true)][EnumMember] Document = 8 + } + + [Test] + public void Flags () + { + var t1 = new TestClass (SomeTypes.Audio | SomeTypes.Image); + var st = ToXml (t1); + var t2 = FromXml (st); + Assert.AreEqual (t2.Types, t1.Types); + } + } +} \ No newline at end of file diff --git a/tests/linker-ios/link all/Info.plist b/tests/linker-ios/link all/Info.plist new file mode 100644 index 000000000000..9dafe4f5bbf2 --- /dev/null +++ b/tests/linker-ios/link all/Info.plist @@ -0,0 +1,32 @@ + + + + + CFBundleDisplayName + LinkAll + CFBundleIdentifier + com.xamarin.linkall + MinimumOSVersion + 5.1.1 + UIDeviceFamily + + 1 + 2 + + UISupportedInterfaceOrientations + + UIInterfaceOrientationPortrait + UIInterfaceOrientationLandscapeLeft + UIInterfaceOrientationLandscapeRight + + UISupportedInterfaceOrientations~ipad + + UIInterfaceOrientationPortrait + UIInterfaceOrientationPortraitUpsideDown + UIInterfaceOrientationLandscapeLeft + UIInterfaceOrientationLandscapeRight + + CFBundleName + LinkAll + + diff --git a/tests/linker-ios/link all/InterfacesTest.cs b/tests/linker-ios/link all/InterfacesTest.cs new file mode 100644 index 000000000000..cb62d254711b --- /dev/null +++ b/tests/linker-ios/link all/InterfacesTest.cs @@ -0,0 +1,111 @@ +// +// Linker interfaces-related Tests +// +// Authors: +// Sebastien Pouliot +// +// Copyright 2013 Xamarin Inc. All rights reserved. +// + +using System; +using System.Reflection; +using System.Runtime.InteropServices; +#if XAMCORE_2_0 +using Foundation; +#else +using MonoTouch.Foundation; +#endif +using NUnit.Framework; + +namespace LinkAll.Interfaces { + + interface I { + void Foo (); + void Bar (); + } + + class A : I { + public void Foo () {} + public void Bar () {} + } + + class B : I { + public void Foo () {} + public void Bar () {} + } + + class UTF8Marshaler : ICustomMarshaler { + + public object MarshalNativeToManaged (IntPtr pNativeData) + { + return null; + } + + public IntPtr MarshalManagedToNative (object managedObject) + { + return IntPtr.Zero; + } + + public int GetNativeDataSize () + { + return 0; + } + + public void CleanUpManagedData (object managedObject) + { + } + + public void CleanUpNativeData (IntPtr pNativeData) + { + } + } + + [TestFixture] + [Preserve (AllMembers = true)] + public class InterfaceTest { + + static void F (I i) + { + i.Bar (); + } + + [Test] + public void Bug10866 () + { + var a = new A (); + a.Foo (); + a.Bar (); + F (new A ()); + + // Foo and Bar methods are both used on A and must be present + Assert.NotNull (typeof(A).GetMethod ("Foo", BindingFlags.Instance | BindingFlags.Public), "A::Foo"); + Assert.NotNull (typeof(A).GetMethod ("Bar", BindingFlags.Instance | BindingFlags.Public), "A::Bar"); + + // I::Foo is never used and can be removed + Assert.Null (typeof(I).GetMethod ("Foo", BindingFlags.Instance | BindingFlags.Public), "I::Foo"); + // I::Bar is used in F so everyone implementing I needs Bar + Assert.NotNull (typeof(I).GetMethod ("Bar", BindingFlags.Instance | BindingFlags.Public), "I::Bar"); + + // Foo and Bar are never used on B - so Foo can be removed + Assert.Null (typeof(B).GetMethod ("Foo", BindingFlags.Instance | BindingFlags.Public), "B::Foo"); + // but Bar cannot since B implements I + Assert.NotNull (typeof(B).GetMethod ("Bar", BindingFlags.Instance | BindingFlags.Public), "B::Bar"); + } + + [DllImport ("/usr/lib/system/libsystem_dnssd.dylib")] + public static extern int DNSServiceGetProperty ( + [MarshalAs (UnmanagedType.CustomMarshaler, MarshalTypeRef = typeof (UTF8Marshaler))] string name, + IntPtr result, ref uint size); + + uint size; + + [Test] + public void Bug16485 () + { + if (size == 1) + DNSServiceGetProperty ("Xamarin", IntPtr.Zero, ref size); + // we don't want to call the function - we only want the AOT compiler to build the CustomMarshaler + Assert.That (size, Is.EqualTo (0), "size"); + } + } +} \ No newline at end of file diff --git a/tests/linker-ios/link all/InternalsTest.cs b/tests/linker-ios/link all/InternalsTest.cs new file mode 100644 index 000000000000..daad43baf3ec --- /dev/null +++ b/tests/linker-ios/link all/InternalsTest.cs @@ -0,0 +1,93 @@ +// +// Link All Unit Tests for __Internal native functions +// +// Authors: +// Sebastien Pouliot +// +// Copyright 2013 Xamarin Inc. All rights reserved. +// + +using System; +using System.Runtime.InteropServices; + +using MonoTouch; +#if XAMCORE_2_0 +using Foundation; +using ObjCRuntime; +#else +using MonoTouch.Foundation; +using MonoTouch.ObjCRuntime; +#endif +using NUnit.Framework; + +namespace LinkAll.InernalCalls { + + [TestFixture] + // we want the tests to be available because we use the linker + [Preserve (AllMembers = true)] + public class InternalsTest { + + [DllImport ("__Internal")] + extern static string xamarin_get_locale_country_code (); + + [Test] + public void RegionInfo_CountryCode () + { + Assert.IsNotNull (xamarin_get_locale_country_code (), "xamarin_get_locale_country_code"); + } + + [DllImport ("__Internal", CharSet=CharSet.Unicode)] + extern static void xamarin_log (string s); + + [Test] + public void Console_Log () + { + xamarin_log ("ascii"); + xamarin_log ("ЉЩщӃ"); + } + +#if !XAMCORE_2_0 + [Test] + public void MessagingApi () + { + Messaging.monotouch_IntPtr_objc_msgSend_IntPtr (IntPtr.Zero, IntPtr.Zero, IntPtr.Zero); + } +#endif + + [DllImport ("__Internal")] + extern static IntPtr xamarin_timezone_get_names (ref int count); + + [Test] + public void TimeZone_Names () + { + int count = 0; + IntPtr array = xamarin_timezone_get_names (ref count); + Assert.That (count, Is.GreaterThan (400), "count"); + for (int i = 0, offset = 0; i < count; i++, offset += IntPtr.Size) { + IntPtr p = Marshal.ReadIntPtr (array, offset); + string s = Marshal.PtrToStringAnsi (p); + Assert.NotNull (s, i.ToString ()); + Marshal.FreeHGlobal (p); + } + Marshal.FreeHGlobal (array); + } + + [DllImport ("__Internal")] + extern static IntPtr xamarin_timezone_get_data (string name, ref int size); + + [Test] + public void TimeZone_Data () + { + int size = 0; + IntPtr data = xamarin_timezone_get_data (null, ref size); + Assert.That (data, Is.Not.EqualTo (IntPtr.Zero), "default"); + Assert.That (size, Is.GreaterThan (0), "default size"); + Marshal.FreeHGlobal (data); + + data = xamarin_timezone_get_data ("America/Montreal", ref size); + Assert.That (data, Is.Not.EqualTo (IntPtr.Zero), "Montreal"); + Assert.That (size, Is.GreaterThan (0), "Montreal size"); + Marshal.FreeHGlobal (data); + } + } +} \ No newline at end of file diff --git a/tests/linker-ios/link all/LinkAllTest.cs b/tests/linker-ios/link all/LinkAllTest.cs new file mode 100644 index 000000000000..4e74e8ee8bc3 --- /dev/null +++ b/tests/linker-ios/link all/LinkAllTest.cs @@ -0,0 +1,539 @@ +// +// Link All [Regression] Tests +// +// Authors: +// Sebastien Pouliot +// +// Copyright 2012-2016 Xamarin Inc. All rights reserved. +// + +using System; +using System.ComponentModel; +using System.Globalization; +using System.IO; +using System.Linq; +using System.Net; +using System.Net.Security; +using System.Reflection; +using System.Security.Cryptography.X509Certificates; + +using MonoTouch; +#if XAMCORE_2_0 +using CoreGraphics; +using Foundation; +using ObjCRuntime; +#if !__WATCHOS__ +using StoreKit; +#endif +using UIKit; +#else +using MonoTouch.CoreGraphics; +using MonoTouch.Foundation; +using MonoTouch.ObjCRuntime; +using MonoTouch.StoreKit; +using MonoTouch.UIKit; +#endif +using NUnit.Framework; + +namespace LinkAll { + + // we DO NOT want the code to be "fully" available + public partial class NotPreserved { + + public byte One { + get; set; + } + + [DefaultValue (2)] + public int Two { + get; set; + } + } + + // nothing directly uses Parent + public class Parent { + // but the nested type is a subclass of NSObject and gets preserved (as it's not part of monotouch.dll) + public class Derived : NSObject { + [Export ("foo")] + public void Foo () {} + } + + public void UnusedMethod () {} + } + + [TestFixture] + // we want the tests to be available because we use the linker + [Preserve (AllMembers = true)] + public class LinkAllRegressionTest { +#if __IOS__ +#if XAMCORE_2_0 + public const string NamespacePrefix = ""; + public const string AssemblyName = "Xamarin.iOS"; +#else + public const string NamespacePrefix = "MonoTouch."; + public const string AssemblyName = "monotouch"; +#endif +#elif __TVOS__ + public const string NamespacePrefix = ""; + public const string AssemblyName = "Xamarin.TVOS"; +#elif __WATCHOS__ + public const string NamespacePrefix = ""; + public const string AssemblyName = "Xamarin.WatchOS"; +#else + #error Unknown platform +#endif + + class TypeAttribute : Attribute { + public TypeAttribute (Type type) {} + } + + [Type (null)] + public void NullTypeInAttribute () + { + // there's no need to execute this test. + // desk #68380. + } + + [Test] + public void GetterOnly () + { + // that ensure the getter is not linked away, + // which means the property will be available for MEF_3862 + NotPreserved np = new NotPreserved (); + Assert.That (np.Two, Is.EqualTo (0), "Two==0"); + PropertyInfo pi = typeof (NotPreserved).GetProperty ("Two"); + // check the *unused* setter absence from the application + Assert.NotNull (pi.GetGetMethod (), "getter"); + Assert.Null (pi.GetSetMethod (), "setter"); + } + + [Test] + public void SetterOnly () + { + // that ensure the setter is not linked away, + NotPreserved np = new NotPreserved (); + np.One = 1; + PropertyInfo pi = typeof (NotPreserved).GetProperty ("One"); + // check the *unused* setter absence from the application + Assert.Null (pi.GetGetMethod (), "getter"); + Assert.NotNull (pi.GetSetMethod (), "setter"); + } + + [Test] + public void MEF_3862 () + { + // note: avoiding using "typeof(DefaultValueAttribute)" in the code + // so the linker does not keep it just because of it + PropertyInfo pi = typeof (NotPreserved).GetProperty ("Two"); + object [] attrs = pi.GetCustomAttributes (false); + bool default_value = false; + foreach (var ca in attrs) { + if (ca.GetType ().Name == "DefaultValueAttribute") { + default_value = true; + break; + } + } + Assert.True (default_value, "DefaultValue"); + } + + class TestPolicy : ICertificatePolicy { + + const int RecoverableTrustFailure = 5; // SecTrustResult + + public TestPolicy () + { + CheckCount = 0; + } + + public int CheckCount { get; private set; } + + public bool CheckValidationResult (ServicePoint srvPoint, X509Certificate certificate, WebRequest request, int certificateProblem) + { + Assert.That (certificateProblem, Is.EqualTo (0), "certificateProblem"); + CheckCount++; + return true; + } + } + + static TestPolicy test_policy = new TestPolicy (); + + [Test] + public void TrustUsingOldPolicy () + { + // Three similar tests exists in dontlink, linkall and linksdk to test 3 different cases + // untrusted, custom ICertificatePolicy and ServerCertificateValidationCallback without + // having caching issues (in S.Net or the SSL handshake cache) + ICertificatePolicy old = ServicePointManager.CertificatePolicy; + try { + ServicePointManager.CertificatePolicy = test_policy; + WebClient wc = new WebClient (); + Assert.IsNotNull (wc.DownloadString ("https://wrench.internalx.com/Wrench/Login.aspx")); + // caching means it will be called at least for the first run, but it might not + // be called again in subsequent requests (unless it expires) + Assert.That (test_policy.CheckCount, Is.GreaterThan (0), "policy checked"); + } + finally { + ServicePointManager.CertificatePolicy = old; + } + } + + [Test] + public void DetectPlatform () + { +#if !__WATCHOS__ + // for (future) nunit[lite] platform detection - if this test fails then platform detection won't work + Assert.NotNull (Type.GetType (NamespacePrefix + "UIKit.UIApplicationDelegate, " + AssemblyName), "UIApplicationDelegate"); +#endif + // and you can trust the old trick with the linker + Assert.NotNull (Type.GetType ("Mono.Runtime"), "Mono.Runtime"); + } + + [Test] +#if !XAMCORE_2_0 + // internal (to be removed) in unified + [Since (9,9)] +#endif +#if !XAMCORE_3_0 + [Availability ()] + [iOS (9,9)] + [Mac (10, 99)] +#endif + [Introduced (PlatformName.None)] + [Deprecated (PlatformName.None)] + [Obsoleted (PlatformName.None)] + [Unavailable (PlatformName.None)] + [ThreadSafe] + public void RemovedAttributes () + { + const string prefix = NamespacePrefix; + const string suffix = ", " + AssemblyName; + + // since we're linking the attributes will NOT be available - even if they are used +#if !XAMCORE_3_0 + Assert.Null (Type.GetType (prefix + "ObjCRuntime.AvailabilityAttribute, " + suffix), "AvailabilityAttribute"); + Assert.Null (Type.GetType (prefix + "ObjCRuntime.iOSAttribute, " + suffix), "AvailabilityAttribute"); + Assert.Null (Type.GetType (prefix + "ObjCRuntime.AvailabilityAttribute, " + suffix), "AvailabilityAttribute"); + Assert.Null (Type.GetType (prefix + "ObjCRuntime.SinceAttribute, " + suffix), "SinceAttribute"); +#endif + Assert.Null (Type.GetType (prefix + "ObjCRuntime.IntroducedAttribute, " + suffix), "IntroducedAttribute"); + Assert.Null (Type.GetType (prefix + "ObjCRuntime.DeprecatedAttribute, " + suffix), "DeprecatedAttribute"); + Assert.Null (Type.GetType (prefix + "ObjCRuntime.ObsoletedAttribute, " + suffix), "ObsoletedAttribute"); + Assert.Null (Type.GetType (prefix + "ObjCRuntime.UnavailableAttribute, " + suffix), "UnavailableAttribute"); + Assert.Null (Type.GetType (prefix + "ObjCRuntime.ThreadSafeAttribute, " + suffix), "ThreadSafeAttribute"); + } + + [Test] + public void Assembly_Load () + { + Assembly mscorlib = Assembly.Load ("mscorlib.dll"); + Assert.NotNull (mscorlib, "mscorlib"); + + Assembly system = Assembly.Load ("System.dll"); + Assert.NotNull (system, "System"); + } + + [Test] + public void Assembly_LoadFile () + { + string filename = Path.GetFileName (GetType ().Assembly.Location); + try { + Assert.NotNull (Assembly.LoadFile (filename), "1"); + } + catch (FileNotFoundException) { + // 2nd chance since FAT 32/64 applications moved the assemblies (but that could prove an issue too) + filename = Path.Combine (IntPtr.Size == 4 ? ".monotouch-32" : ".monotouch-64", filename); + Assert.NotNull (Assembly.LoadFile (filename), "2"); + } + } + + [Test] + public void Assembly_LoadFrom () + { + string filename = Path.GetFileName (GetType ().Assembly.Location); + try { + Assert.NotNull (Assembly.LoadFrom (filename), "1"); + } + catch (FileNotFoundException) { + // 2nd chance since FAT 32/64 applications moved the assemblies (but that could prove an issue too) + filename = Path.Combine (IntPtr.Size == 4 ? ".monotouch-32" : ".monotouch-64", filename); + Assert.NotNull (Assembly.LoadFrom (filename), "2"); + } + } + + [Test] + public void Assembly_ReflectionOnlyLoadFrom () + { + string filename = Path.GetFileName (GetType ().Assembly.Location); + try { + Assert.NotNull (Assembly.ReflectionOnlyLoadFrom (filename), "1"); + } + catch (FileNotFoundException) { + // 2nd chance since FAT 32/64 applications moved the assemblies (but that could prove an issue too) + filename = Path.Combine (IntPtr.Size == 4 ? ".monotouch-32" : ".monotouch-64", filename); + Assert.NotNull (Assembly.ReflectionOnlyLoadFrom (filename), "2"); + } + } + + [Test] + public void SystemDataSqlClient () + { + // notes: + // * this test is mean to fail when building the application using a Community or Indie licenses + // * linksdk.app references System.Data (assembly) but not types in SqlClient namespace + using (var sc = new System.Data.SqlClient.SqlConnection ()) { + Assert.NotNull (sc); + } + } + +#if !__TVOS__ && !__WATCHOS__ + [Test] + public void Pasteboard_ImagesTest () + { + string file = Path.Combine (NSBundle.MainBundle.ResourcePath, "basn3p08.png"); + using (var dp = new CGDataProvider (file)) { + using (var cgimg = CGImage.FromPNG (dp, null, false, CGColorRenderingIntent.Default)) { + using (var img = new UIImage (cgimg)) { + UIPasteboard.General.Images = new UIImage[] { img }; + Assert.AreEqual (1, UIPasteboard.General.Images.Length, "a - length"); + + UIPasteboard.General.Images = new UIImage[] { img, img }; + Assert.AreEqual (2, UIPasteboard.General.Images.Length, "b - length"); + Assert.IsNotNull (UIPasteboard.General.Images [0], "b - nonnull[0]"); + Assert.IsNotNull (UIPasteboard.General.Images [1], "b - nonnull[0]"); + } + } + } + } +#endif // !__TVOS__ + + [Test] + public void UltimateBindings () + { + Assert.IsNotNull (Bindings.Test.UltimateMachine.SharedInstance, "SharedInstance"); + } + + #region bug 14456 + + [TypeConverter (typeof (TestEnumTypeConverter))] + public enum TestEnum { + One,Two + } + + [Preserve (AllMembers = true)] + public class TestEnumTypeConverter : System.ComponentModel.TypeConverter { + + public override object ConvertTo (ITypeDescriptorContext context, CultureInfo culture, object value, Type destinationType) + { + return "hello"; + } + } + + [Test] + public void Bug14456 () + { + var tc = TypeDescriptor.GetConverter (typeof (TestEnum)); + // not using Is.TypeOf since it would give additional clue to the linker + Assert.That (tc.GetType ().Name, Is.EqualTo ("TestEnumTypeConverter"), "TestEnumTypeConverter"); + // notes: + // * without [Preserve (AllMembers = true)] -> MissingMethodException : Default constructor + // * without [TypeConverter (typeof (TestEnumTypeConverter))] -> EnumConverter + } + + #endregion + + [Test] + public void SingleEpsilon_Compare () + { + if (Runtime.Arch == Arch.DEVICE) + Assert.Ignore ("Known to fail on devices, see bug #15802"); + // works on some ARM CPU (e.g. iPhone5S) but not others (iPad4 or iPodTouch5) + Assert.That (Single.Epsilon, Is.Not.EqualTo (0f), "Epsilon"); + Assert.That (-Single.Epsilon, Is.Not.EqualTo (0f), "-Epsilon"); + } + + [Test] + public void SingleEpsilon_ToString () + { + if (Runtime.Arch == Arch.DEVICE) + Assert.Ignore ("Known to fail on devices, see bug #15802"); + var ci = CultureInfo.InvariantCulture; + Assert.That (Single.Epsilon.ToString (ci), Is.EqualTo ("1.401298E-45"), "Epsilon.ToString()"); + Assert.That ((-Single.Epsilon).ToString (ci), Is.EqualTo ("-1.401298E-45"), "-Epsilon.ToString()"); + } + + [Test] + public void DoubleEpsilon_Compare () + { + if (Runtime.Arch == Arch.DEVICE) + Assert.Ignore ("Known to fail on devices, see bug #15802"); + // works on some ARM CPU (e.g. iPhone5S) but not others (iPad4 or iPodTouch5) + Assert.That (Double.Epsilon, Is.Not.EqualTo (0f), "Epsilon"); + Assert.That (-Double.Epsilon, Is.Not.EqualTo (0f), "-Epsilon"); + } + + [Test] + public void DoubleEpsilon_ToString () + { + if (Runtime.Arch == Arch.DEVICE) + Assert.Ignore ("Known to fail on devices, see bug #15802"); + var ci = CultureInfo.InvariantCulture; + // note: unlike Single this works on both my iPhone5S and iPodTouch5 + Assert.That (Double.Epsilon.ToString (ci), Is.EqualTo ("4.94065645841247E-324"), "Epsilon.ToString()"); + Assert.That ((-Double.Epsilon).ToString (ci), Is.EqualTo ("-4.94065645841247E-324"), "-Epsilon.ToString()"); + } + + [Test] + public void AssemblyReferences_16213 () + { + foreach (var assembly in typeof (System.Data.AcceptRejectRule).Assembly.GetReferencedAssemblies ()) { + // Unlike the original bug report the unit tests uses Mono.Data.Tds so it will be part of the .app + // so we check for System.Transactions which is not used (but referenced by the original System.Data) + if (assembly.Name == "System.Transactions") + Assert.Fail ("System.Transactions reference should have removed by the linker"); + } + } + +#if !__WATCHOS__ + [Test] + public void OpenTk10_Preserved () + { + // that will bring OpenTK-1.0 into the .app + OpenTK.WindowState state = OpenTK.WindowState.Normal; + + var gl = Type.GetType ("OpenTK.Graphics.ES11.GL, OpenTK-1.0", false); + Assert.NotNull (gl, "ES11/GL"); + var core = Type.GetType ("OpenTK.Graphics.ES11.GL/Core, OpenTK-1.0", false); + Assert.NotNull (core, "ES11/Core"); + + gl = Type.GetType ("OpenTK.Graphics.ES20.GL, OpenTK-1.0", false); + Assert.NotNull (gl, "ES20/GL"); + core = Type.GetType ("OpenTK.Graphics.ES20.GL/Core, OpenTK-1.0", false); + Assert.NotNull (core, "ES20/Core"); + } +#endif // !__WATCHOS__ + + [Test] + public void NestedNSObject () + { + // Parent type is not used - but it's not linked out + var p = Type.GetType ("LinkAll.Parent"); + Assert.NotNull (p, "Parent"); + // because a nested type is a subclass of NSObject (and not part of monotouch.dll) + var n = p.GetNestedType ("Derived"); + Assert.NotNull (n, "Derived"); + // however other stuff in Parent, like unused methods, will be removed + Assert.Null (p.GetMethod ("UnusedMethod"), "unused method"); + // while exported stuff will be present + Assert.NotNull (n.GetMethod ("Foo"), "unused Export method"); + } + + [Test] + public void Bug20363 () + { + // testing compile time error + CancelEventArgs cea = new CancelEventArgs (); + Assert.NotNull (cea, "CancelEventArgs"); + } + + string GetField (object o, string s) + { + var f = o.GetType ().GetField (s, BindingFlags.Instance | BindingFlags.NonPublic); + if (f == null) + return s; + //Console.WriteLine (f.GetValue (o)); + return null; + } + + string FromPattern (string pattern, object o) + { + var s = GetField (o, ""); + if (s != null) + return s; + s = GetField (o, ""); + if (s != null) + return s; + return GetField (o, ""); + } + + [Test] + public void AnonymousType () + { + var result = FromPattern ("/{action}/{id}.{contentType}", new { + action = "foo", + id = 1234, + contentType = "xml" + }); + Assert.Null (result, result); + } + +#if !__WATCHOS__ + [Test] + public void Events () + { + using (var pr = new SKProductsRequest ()) { + Assert.Null (pr.WeakDelegate, "none"); + // event on SKProductsRequest itself + pr.ReceivedResponse += (object sender, SKProductsRequestResponseEventArgs e) => {}; + + var t = pr.WeakDelegate.GetType (); + Assert.That (t.Name, Is.EqualTo ("_SKProductsRequestDelegate"), "delegate"); + + var fi = t.GetField ("receivedResponse", BindingFlags.NonPublic | BindingFlags.Instance); + Assert.NotNull (fi, "receivedResponse"); + var value = fi.GetValue (pr.WeakDelegate); + Assert.NotNull (value, "value"); + +#if XAMCORE_2_0 + // and on the SKRequest defined one + pr.RequestFailed += (object sender, SKRequestErrorEventArgs e) => {}; + // and the existing (initial field) is still set + fi = t.GetField ("receivedResponse", BindingFlags.NonPublic | BindingFlags.Instance); + Assert.NotNull (fi, "receivedResponse/SKRequest"); +#else + // In Classic SKRequest also defines a RequestFailed event, so make sure we get the SKRequest one + // that's because event are re-defined (new) in classic + ((SKRequest) pr).RequestFailed += (object sender, SKRequestErrorEventArgs e) => {}; + + t = pr.WeakDelegate.GetType (); + Assert.That (t.Name, Is.EqualTo ("_SKRequestDelegate"), "delegate-2"); + + fi = t.GetField ("receivedResponse", BindingFlags.NonPublic | BindingFlags.Instance); + Assert.Null (fi, "receivedResponse/SKRequest"); +#endif + } + } +#endif // !__WATCHOS__ + + [Test] + public void Aot_27116 () + { + var nix = (from nic in System.Net.NetworkInformation.NetworkInterface.GetAllNetworkInterfaces () + where nic.Id.StartsWith ("en") || nic.Id.StartsWith ("pdp_ip") select nic); + Assert.NotNull (nix); + } + + [Test] + public void TlsProvider_Legacy () + { + var provider = Mono.Security.Interface.MonoTlsProviderFactory.GetProvider (); + Assert.NotNull (provider, "provider"); + Assert.That (provider.ID, Is.EqualTo (new Guid ("97d31751-d0b3-4707-99f7-a6456b972a19")), "correct provider"); + } + + [Test] + public void OldTlsProvider_Selected () + { + // make test work for classic (monotouch) and unified (iOS, tvOS and watchOS) + var fqn = typeof (NSObject).AssemblyQualifiedName.Replace ("Foundation.NSObject", "Security.Tls.OldTlsProvider"); + Assert.NotNull (Type.GetType (fqn), "Should be included"); + } + + [Test] + public void AppleTls_OptOut () + { + // make test work for classic (monotouch) and unified (iOS, tvOS and watchOS) + var fqn = typeof (NSObject).AssemblyQualifiedName.Replace ("Foundation.NSObject", "Security.Tls.AppleTlsProvider"); + Assert.Null (Type.GetType (fqn), "Should not be included"); + } + } +} diff --git a/tests/linker-ios/link all/LinqExpressionTest.cs b/tests/linker-ios/link all/LinqExpressionTest.cs new file mode 100644 index 000000000000..f0862601993a --- /dev/null +++ b/tests/linker-ios/link all/LinqExpressionTest.cs @@ -0,0 +1,33 @@ +using System; +using System.Linq.Expressions; +#if XAMCORE_2_0 +using Foundation; +#else +using MonoTouch.Foundation; +#endif +using NUnit.Framework; + +namespace LinkAll.Linq { + + [TestFixture] + // we want the tests to be available because we use the linker + [Preserve (AllMembers = true)] + public class LinqExpressionTest { + + // Normally this test would have been included in linksdk.app - but there's already + // some code that (indirectly) includes the code we want to test (so it can't fail) + + delegate object Bug14863Delegate (); + + [Test] + public void Expression_T_Ctor () + { + var ctor = typeof (LinqExpressionTest).GetConstructor (Type.EmptyTypes); + var expr = Expression.New (ctor, new Expression [0]); + Assert.NotNull (Expression.Lambda (typeof(Bug14863Delegate), expr, null), "Lambda"); + // note: reflection is used to create an instance of Expression using an internal ctor + // it can be indirectly "preserved" by other code (in Expression) but it can fail in other cases + // ref: https://bugzilla.xamarin.com/show_bug.cgi?id=14863 + } + } +} \ No newline at end of file diff --git a/tests/linker-ios/link all/MEFTests.cs b/tests/linker-ios/link all/MEFTests.cs new file mode 100644 index 000000000000..190b093eaca7 --- /dev/null +++ b/tests/linker-ios/link all/MEFTests.cs @@ -0,0 +1,84 @@ +using System; +using System.Collections.Generic; +using System.ComponentModel.Composition; +using System.ComponentModel.Composition.Hosting; +using System.Linq; +using System.Reflection; +#if XAMCORE_2_0 +using Foundation; +#else +using MonoTouch.Foundation; +#endif +using NUnit.Framework; + +namespace LinkAll.Mef { + + // From Desk Case 70807 + public interface IStorageType + { + } + + [System.ComponentModel.Composition.Export(typeof (IStorageType))] + [Preserve (AllMembers = true)] + public class Storage : IStorageType + { + } + + [Preserve (AllMembers = true)] + [TestFixture] + public class MEFTests + { + CompositionContainer _container; + + [ImportMany] + public IEnumerable> StorageTypes { get; set; } + + [Test] + public void MEF_Basic_Import_Test () + { + var catalog = new AggregateCatalog (); + //Adds all the parts found in the same assembly as the Program class + catalog.Catalogs.Add (new AssemblyCatalog (typeof (Application).Assembly)); + + //Create the CompositionContainer with the parts in the catalog + _container = new CompositionContainer (catalog); + + this._container.SatisfyImportsOnce (this); + + Assert.IsTrue (StorageTypes.Count () > 0, "No MEF imports found?"); + } + + [Test] + public void ExportFactoryCreator () + { + // the above code makes sure that ExportFactoryCreator is present + var efc = Type.GetType ("System.ComponentModel.Composition.ReflectionModel.ExportFactoryCreator, System.ComponentModel.Composition"); + Assert.NotNull (efc, "ExportFactoryCreator"); + + // and there's nothing else that refers to them - hence bug: https://bugzilla.xamarin.com/show_bug.cgi?id=29063 + // as it's used thru reflection in CreateStronglyTypedExportFactoryFactory + var t = efc.GetMethod ("CreateStronglyTypedExportFactoryOfT", BindingFlags.Public | BindingFlags.NonPublic | BindingFlags.Instance); // same binding flags as MS code + Assert.NotNull (t, "CreateStronglyTypedExportFactoryOfT"); + var tm = efc.GetMethod ("CreateStronglyTypedExportFactoryOfTM", BindingFlags.Public | BindingFlags.NonPublic | BindingFlags.Instance); // same binding flags as MS code + Assert.NotNull (tm, "CreateStronglyTypedExportFactoryOfTM"); + } + + [Test] + public void ExportServices () + { + var es = Type.GetType ("System.ComponentModel.Composition.ExportServices, System.ComponentModel.Composition"); + Assert.NotNull (es, "ExportServices"); + // unlike the test code for ExportFactoryCreator the method can be marked by other call site, so this test is not 100% conclusive + + // used, thru reflection, from CreateStronglyTypedLazyFactory method + var t = es.GetMethod ("CreateStronglyTypedLazyOfT", BindingFlags.NonPublic | BindingFlags.Static); // same binding flags as MS code + Assert.NotNull (t, "CreateStronglyTypedLazyOfT"); + var tm = es.GetMethod ("CreateStronglyTypedLazyOfTM", BindingFlags.NonPublic | BindingFlags.Static); // same binding flags as MS code + Assert.NotNull (tm, "CreateStronglyTypedLazyOfTM"); + + // used, thru reflection, from CreateSemiStronglyTypedLazyFactory method + var l = es.GetMethod ("CreateSemiStronglyTypedLazy", BindingFlags.NonPublic | BindingFlags.Static); // same binding flags as MS code + Assert.NotNull (l, "CreateSemiStronglyTypedLazy"); + } + } +} diff --git a/tests/linker-ios/link all/Main.cs b/tests/linker-ios/link all/Main.cs new file mode 100644 index 000000000000..c9b0815dd93e --- /dev/null +++ b/tests/linker-ios/link all/Main.cs @@ -0,0 +1,23 @@ +using System; + +#if XAMCORE_2_0 +using UIKit; +#else +using MonoTouch.UIKit; +#endif + +namespace LinkAll +{ + public class Application + { +#if !__WATCHOS__ + // This is the main entry point of the application. + static void Main (string[] args) + { + // if you want to use a different Application Delegate class from "AppDelegate" + // you can specify it here. + UIApplication.Main (args, null, "AppDelegate"); + } +#endif // !__WATCHOS__ + } +} diff --git a/tests/linker-ios/link all/PreserveTest.cs b/tests/linker-ios/link all/PreserveTest.cs new file mode 100644 index 000000000000..f83addf0961f --- /dev/null +++ b/tests/linker-ios/link all/PreserveTest.cs @@ -0,0 +1,168 @@ +// +// Preserve tests +// +// Authors: +// Sebastien Pouliot +// +// Copyright 2013-2016 Xamarin Inc. All rights reserved. +// + +using System; +using System.Reflection; +#if XAMCORE_2_0 +using Foundation; +using ObjCRuntime; +#else +using MonoTouch.Foundation; +using MonoTouch.ObjCRuntime; +#endif +using NUnit.Framework; + +// this will preserve the specified type (only) +[assembly: Preserve (typeof (LinkAll.Attributes.TypeWithoutMembers))] + +// this will preserve the specified type with all it's members +[assembly: Preserve (typeof (LinkAll.Attributes.TypeWithMembers), AllMembers = true)] + +// as the preserved field is an attribute this means that [Obfuscation] becomes like [Preserve] +// IOW preserving the attribute does not do much good if what it decorates gets removed +[assembly: Preserve (typeof (ObfuscationAttribute))] + +namespace LinkAll.Attributes { + + // type and members preserved by assembly-level attribute above + class TypeWithMembers { + + public string Present { get; set; } + } + + // type (only, not members) preserved by assembly-level attribute above + class TypeWithoutMembers { + + public string Absent { get; set; } + } + + class MemberWithCustomAttribute { + + // since [Obfuscation] was manually preserved then we'll preserve everything that's decorated with the attribute + [Obfuscation] + public string Custom { get; set; } + } + + [TestFixture] + // we want the tests to be available because we use the linker + [Preserve (AllMembers = true)] + public class PreserveTest { + +#if DEBUG + const bool Debug = true; +#else + const bool Debug = false; +#endif +#if XAMCORE_2_0 + const string NamespacePrefix = ""; + string AssemblyName = typeof (NSObject).Assembly.ToString (); +#else + const string NamespacePrefix = "MonoTouch."; + const string AssemblyName = "monotouch"; +#endif + + [Test] + public void PreserveTypeWithMembers () + { + var t = Type.GetType ("LinkAll.Attributes.TypeWithMembers"); + // both type and members are preserved + Assert.NotNull (t, "type"); + Assert.NotNull (t.GetProperty ("Present"), "members"); + } + + [Test] + public void PreserveTypeWithoutMembers () + { + var t = Type.GetType ("LinkAll.Attributes.TypeWithoutMembers"); + // type is preserved + Assert.NotNull (t, "type"); + // but we did not ask the linker to preserve it's members + Assert.Null (t.GetProperty ("Absent"), "members"); + } + + [Test] + public void PreserveTypeWithCustomAttribute () + { + var t = Type.GetType ("LinkAll.Attributes.MemberWithCustomAttribute"); + // both type and members are preserved - in this case the type is preserved because it's member was + Assert.NotNull (t, "type"); + // and that member was preserved because it's decorated with a preserved attribute + Assert.NotNull (t.GetProperty ("Custom"), "members"); + } + + [Test] + public void Class_LookupFullName () + { + var klass = Type.GetType (NamespacePrefix + "ObjCRuntime.Class, " + AssemblyName); + Assert.NotNull (klass, "Class"); + // only required (and preserved) for debug builds + var method = klass.GetMethod ("LookupFullName", BindingFlags.NonPublic | BindingFlags.Static); + // note: since iOS/runtime unification this is being called by ObjCRuntime.Runtime.LookupManagedTypeName + // and will never be removed (even on Release builds) + Assert.NotNull (method, "LookupFullName"); + } + + [Test] + public void Runtime_RegisterEntryAssembly () + { + var klass = Type.GetType (NamespacePrefix + "ObjCRuntime.Runtime, " + AssemblyName); + Assert.NotNull (klass, "Runtime"); + // RegisterEntryAssembly is only needed for the simulator (not on devices) so it's only preserved for sim builds + var method = klass.GetMethod ("RegisterEntryAssembly", BindingFlags.NonPublic | BindingFlags.Static, null, new [] { typeof (Assembly) }, null); + Assert.That (method == null, Is.EqualTo (Runtime.Arch == Arch.DEVICE), "RegisterEntryAssembly"); + } + + [Test] + public void MonoTouchException_Unconditional () + { + var klass = Type.GetType (NamespacePrefix + "Foundation.MonoTouchException, " + AssemblyName); + Assert.NotNull (klass, "MonoTouchException"); + } + + [Test] + public void Class_Unconditional () + { + var klass = Type.GetType (NamespacePrefix + "ObjCRuntime.Class, " + AssemblyName); + Assert.NotNull (klass, "Class"); + // handle is unconditionally preserved + var field = klass.GetField ("handle", BindingFlags.NonPublic | BindingFlags.Instance); + Assert.NotNull (field, "handle"); + } + + [Test] + public void Runtime_Unconditional () + { + var klass = Type.GetType (NamespacePrefix + "ObjCRuntime.Runtime, " + AssemblyName); + Assert.NotNull (klass, "Runtime"); + // Initialize, RegisterAssembly... are unconditionally preserved + var method = klass.GetMethod ("Initialize", BindingFlags.NonPublic | BindingFlags.Static); + Assert.NotNull (method, "Initialize"); + method = klass.GetMethod ("RegisterAssembly", BindingFlags.Public | BindingFlags.Static); + Assert.NotNull (method, "RegisterAssembly"); + method = klass.GetMethod ("RegisterNSObject", BindingFlags.NonPublic | BindingFlags.Static, null, new Type[] { typeof (NSObject), typeof (IntPtr) }, null); + Assert.NotNull (method, "RegisterNSObject"); + method = klass.GetMethod ("GetBlockWrapperCreator", BindingFlags.Public | BindingFlags.Static | BindingFlags.NonPublic, null, new Type[] { typeof (MethodInfo), typeof (int) }, null); + Assert.NotNull (method, "GetBlockWrapperCreator"); + method = klass.GetMethod ("CreateBlockProxy", BindingFlags.Public | BindingFlags.Static | BindingFlags.NonPublic, null, new Type[] { typeof (MethodInfo), typeof (IntPtr) }, null); + Assert.NotNull (method, "CreateBlockProxy"); + } + + [Test] + public void Selector_Unconditional () + { + var klass = Type.GetType (NamespacePrefix + "ObjCRuntime.Selector, " + AssemblyName); + Assert.NotNull (klass, "Selector"); + // handle and is unconditionally preserved + var field = klass.GetField ("handle", BindingFlags.NonPublic | BindingFlags.Instance); + Assert.NotNull (field, "handle"); + var method = klass.GetMethod ("GetHandle", BindingFlags.Public | BindingFlags.Static); + Assert.NotNull (method, "GetHandle"); + } + } +} \ No newline at end of file diff --git a/tests/linker-ios/link all/SealerTest.cs b/tests/linker-ios/link all/SealerTest.cs new file mode 100644 index 000000000000..d6dab5737d3d --- /dev/null +++ b/tests/linker-ios/link all/SealerTest.cs @@ -0,0 +1,71 @@ +// Copyright 2016 Xamarin Inc. All rights reserved. + +using System; +#if XAMCORE_2_0 +using Foundation; +#else +using MonoTouch.Foundation; +#endif +using NUnit.Framework; + +namespace Linker.Sealer { + + [Preserve (AllMembers = true)] + public class Unsealable { + + public virtual bool A () { return true; } + public virtual bool B () { return false; } + } + + [Preserve (AllMembers = true)] + public class Sealable : Unsealable { + public override bool B () { return true; } + } + + [TestFixture] + [Preserve (AllMembers = true)] + public class SealerTest { + + [Test] + public void Sealed () + { + // this can not be optimized into a sealed type + Assert.False (typeof (Unsealable).IsSealed, "Unsealed"); +#if DEBUG + // this is not a sealed type (in the source) + Assert.False (typeof (Sealable).IsSealed, "Sealed"); +#else + // but it can be optimized / sealed as nothing else is (or can) subclass it + Assert.True (typeof (Sealable).IsSealed, "Sealed"); +#endif + } + + [Test] + public void Final () + { + var t = typeof (Sealable); +#if DEBUG + // this is not a sealed method (in the source) + Assert.False (t.GetMethod ("B").IsFinal, "Not Final"); +#else + // but it can be optimized / sealed as nothing else is (or can) overrides it + Assert.True (t.GetMethod ("B").IsFinal, "Final"); +#endif + } + + [Test] + public void Virtual () + { + var t = typeof (Sealable); +#if DEBUG + // both methods are virtual (iin the source) + Assert.True (t.GetMethod ("A").IsVirtual, "A"); + Assert.True (t.GetMethod ("B").IsVirtual, "B"); +#else + // but A can be de-virtualized as it overrides nothing and is not overridden + Assert.False (t.GetMethod ("A").IsVirtual, "A"); + Assert.True (t.GetMethod ("B").IsVirtual, "B"); +#endif + } + } +} diff --git a/tests/linker-ios/link all/SerializationTest.cs b/tests/linker-ios/link all/SerializationTest.cs new file mode 100644 index 000000000000..5f2315367103 --- /dev/null +++ b/tests/linker-ios/link all/SerializationTest.cs @@ -0,0 +1,96 @@ +// +// Link All [Regression] Tests for Serialization +// +// Authors: +// Sebastien Pouliot +// +// Copyright 2016 Xamarin Inc. All rights reserved. +// + +using System; +using System.Runtime.Serialization; +#if XAMCORE_2_0 +using Foundation; +#else +using MonoTouch.Foundation; +#endif +using NUnit.Framework; + +namespace LinkAll.Serialization { + + [Serializable] + public class Unused { + + [OnDeserializing] + void Deserializing () + { + } + + [OnDeserialized] + void Deserialized () + { + } + + [OnSerializing] + void Serializing () + { + } + + [OnSerialized] + void Serialized () + { + } + } + + [Serializable] + public class Used { + + [OnDeserializing] + void Deserializing () + { + } + + [OnDeserialized] + void Deserialized () + { + } + + [OnSerializing] + void Serializing () + { + } + + [OnSerialized] + void Serialized () + { + } + } + + [TestFixture] + // we want the tests to be available because we use the linker + [Preserve (AllMembers = true)] + public class SerializationAttributeTests { + + [Test] + public void UnusedType () + { + // the serialization attributes only keeps the method(s) if the type was used + var t = Type.GetType ("LinkAll.Serialization.Unused"); + // since it's not used in the app then it's removed by the linker + Assert.Null (t, "type"); + } + + [Test] + public void UsedType () + { + // the serialization attributes only keeps the method(s) if the type was used + var t = Type.GetType ("LinkAll.Serialization.Used"); + // since it's used here... + Assert.NotNull (new Used (), "reference"); + // it's not removed by the linker + Assert.NotNull (t, "type"); + // and since it's not the 4 decorated methods are also kept (even if uncalled) + Assert.That (t.GetMethods ().Length, Is.EqualTo (4), "4"); + } + } +} diff --git a/tests/linker-ios/link all/StructLayoutTest.cs b/tests/linker-ios/link all/StructLayoutTest.cs new file mode 100644 index 000000000000..2ef9634b7149 --- /dev/null +++ b/tests/linker-ios/link all/StructLayoutTest.cs @@ -0,0 +1,113 @@ +// +// Link All [Regression] Tests +// +// Authors: +// Sebastien Pouliot +// +// Copyright 2012 Xamarin Inc. All rights reserved. +// + +using System; +using System.Runtime.InteropServices; +#if XAMCORE_2_0 +using Foundation; +#else +using MonoTouch.Foundation; +#endif +using NUnit.Framework; + +namespace LinkAll.Layout { + + struct DefaultStruct { + public int never_used; + public int used; + } + + [StructLayout (LayoutKind.Auto)] + struct AutoStruct { + public int never_used; + public int used; + } + + [StructLayout (LayoutKind.Sequential)] + struct SequentialStruct { + public int never_used; + public int used; + } + + [StructLayout (LayoutKind.Explicit)] + struct ExplicitStruct { + [FieldOffset (0)] + public int never_used; + [FieldOffset (4)] + public int used; + [FieldOffset (8)] + public int never_ever_used; + } + + [TestFixture] + // we want the tests to be available because we use the linker + [Preserve (AllMembers = true)] + public class StructLayoutTest { + + [Test] + public void DefaultLayoutStruct () // sequential + { + DefaultStruct c = new DefaultStruct (); + c.used = 1; + Assert.That (Marshal.SizeOf (c), Is.EqualTo (8), "2 fields"); + var t = typeof (DefaultStruct); + var fields = t.GetFields (); + Assert.That (fields.Length, Is.EqualTo (2), "Length"); + + Assert.False (t.IsAutoLayout, "IsAutoLayout"); + Assert.False (t.IsExplicitLayout, "IsExplicitLayout"); + Assert.True (t.IsLayoutSequential, "IsLayoutSequential"); + } + + [Test] + public void AutoLayoutStruct () + { + AutoStruct c = new AutoStruct (); + c.used = 1; + // can't ask SizeOf on Auto + var t = typeof (AutoStruct); + var fields = t.GetFields (); + Assert.That (fields.Length, Is.EqualTo (2), "Length"); + + Assert.True (t.IsAutoLayout, "IsAutoLayout"); + Assert.False (t.IsExplicitLayout, "IsExplicitLayout"); + Assert.False (t.IsLayoutSequential, "IsLayoutSequential"); + } + + [Test] + public void LayoutSequential () + { + SequentialStruct c = new SequentialStruct (); + c.used = 1; + Assert.That (Marshal.SizeOf (c), Is.EqualTo (8), "2 fields"); + var t = typeof (SequentialStruct); + var fields = t.GetFields (); + Assert.That (fields.Length, Is.EqualTo (2), "Length"); + + Assert.False (t.IsAutoLayout, "IsAutoLayout"); + Assert.False (t.IsExplicitLayout, "IsExplicitLayout"); + Assert.True (t.IsLayoutSequential, "IsLayoutSequential"); + } + + [Test] + public void ExplicitLayout () + { + ExplicitStruct c = new ExplicitStruct (); + c.used = 1; + Assert.That (Marshal.SizeOf (c), Is.GreaterThanOrEqualTo (12), "3 fields"); + var t = typeof (ExplicitStruct); + var fields = t.GetFields (); + Assert.That (fields.Length, Is.EqualTo (3), "Length"); + + Assert.False (t.IsAutoLayout, "IsAutoLayout"); + Assert.True (t.IsExplicitLayout, "IsExplicitLayout"); + Assert.False (t.IsLayoutSequential, "IsLayoutSequential"); + } + } +} \ No newline at end of file diff --git a/tests/linker-ios/link all/XmlSerializationTest.cs b/tests/linker-ios/link all/XmlSerializationTest.cs new file mode 100644 index 000000000000..34da3861a1d4 --- /dev/null +++ b/tests/linker-ios/link all/XmlSerializationTest.cs @@ -0,0 +1,79 @@ +// +// Link All Xml Serialization Tests +// +// Authors: +// Sebastien Pouliot +// +// Copyright 2012 Xamarin Inc. All rights reserved. +// + +using System; +using System.IO; +using System.Xml; +using System.Xml.Serialization; + +#if XAMCORE_2_0 +using Foundation; +#else +using MonoTouch.Foundation; +#endif + +using NUnit.Framework; + +namespace LinkAll.Serialization.Xml { + + [Serializable] + [XmlRoot ("rsp", IsNullable = false)] + public class XmlResult { + [XmlAttribute ("stat")] + public int StatusCode { get; set; } + + [XmlElement ("photos")] + [XmlElement ("photosets")] + public T Result { get; set; } + } + + [Serializable] + [XmlRoot ("rsp")] + public class XmlField { + [XmlElement ("photos")] + [XmlElement ("photosets")] + public T Result; + } + + [TestFixture] + // we want the tests to be available because we use the linker + [Preserve (AllMembers = true)] + public class XmlSerializationTest { + + [Test] + public void GenericProperty_Bug5543 () + { + XmlResult r = new XmlResult (); + r.Result = "5543"; + r.StatusCode = 10; + + var serializer = new XmlSerializer (typeof (XmlResult)); + using (var ms = new MemoryStream ()) { + serializer.Serialize (ms, r); + r.Result = String.Empty; + r.StatusCode = -1; + + ms.Position = 0; + XmlResult back = (XmlResult) serializer.Deserialize (ms); + + Assert.That (back.Result, Is.EqualTo ("5543"), "Result"); + Assert.That (back.StatusCode, Is.EqualTo (10), "StatusCode"); + } + } + + [Test] + public void GenericField () + { + XmlField f = new XmlField (); + f.Result = "5543"; + // not valid for serialization but the linker should not have issue with that + } + } +} + diff --git a/tests/linker-ios/link all/link all.csproj b/tests/linker-ios/link all/link all.csproj new file mode 100644 index 000000000000..6178f1bb5df3 --- /dev/null +++ b/tests/linker-ios/link all/link all.csproj @@ -0,0 +1,123 @@ + + + + Debug + iPhoneSimulator + 8.0.30703 + 2.0 + {370CC763-EDC3-41DA-A21A-D4C82CABEFE4} + {6BC8ED88-2882-458C-8E55-DFD12B67127B};{FAE04EC0-301F-11D3-BF4B-00C04F79EFBC} + Exe + linkall + link all + MonoTouch + + + True + full + False + bin\iPhoneSimulator\Debug + DEBUG;LINKALL; + prompt + 4 + False + True + Full + mideast,other + --registrar=static --tls-provider=legacy + i386 + + + none + False + bin\iPhoneSimulator\Release + prompt + 4 + False + Full + mideast,other + i386 + LINKALL; + --tls-provider=legacy + + + True + full + False + bin\iPhone\Debug + DEBUG;LINKALL; + prompt + 4 + False + iPhone Developer + True + Full + mideast,other + ARMv7 + --tls-provider=legacy -gcc_flags="-UhoItsB0rken" + + + none + False + bin\iPhone\Release + prompt + 4 + False + iPhone Developer + Full + mideast,other + True + ARMv7 + -v -v -v -v --tls-provider=legacy + LINKALL; + + + + + + + + + + + + + + + + + + + + + + + + + + + OptimizeGeneratedCodeTest.cs + + + + + + + + + ReflectionTest.cs + + + + + + {FE6EDEE9-ADF6-4F42-BCF2-B68C0A44EC3D} + BundledResources + + + {D6667423-EDD8-4B50-9D98-1AC5D8A8A4EA} + bindings-test + + + + \ No newline at end of file diff --git a/tests/linker-ios/link sdk/AotBugs.cs b/tests/linker-ios/link sdk/AotBugs.cs new file mode 100644 index 000000000000..b6324bef4518 --- /dev/null +++ b/tests/linker-ios/link sdk/AotBugs.cs @@ -0,0 +1,620 @@ +using System; +using System.Collections.Concurrent; +using System.Collections.Generic; +using System.Collections.ObjectModel; +#if !__WATCHOS__ +using System.Drawing; +#endif +using System.Linq; +using System.Threading.Tasks; +using System.Runtime.CompilerServices; +#if XAMCORE_2_0 +using CoreGraphics; +using Foundation; +using ObjCRuntime; +#else +using MonoTouch.CoreGraphics; +using MonoTouch.Foundation; +using MonoTouch.ObjCRuntime; +#endif + +#if XAMCORE_2_0 +using RectangleF=CoreGraphics.CGRect; +using SizeF=CoreGraphics.CGSize; +using PointF=CoreGraphics.CGPoint; +#else +using nfloat=global::System.Single; +using nint=global::System.Int32; +using nuint=global::System.UInt32; +#endif + +using NUnit.Framework; + +namespace LinkSdk.Aot { + + static class AotExtension { + + // https://bugzilla.xamarin.com/show_bug.cgi?id=3285 + public static IEnumerable GetInterfaces(this Type type, Type interfaceType) + { + Type[] interfaces = type.GetInterfaces(); + foreach (Type t in interfaces) { + Type typeToCheck = t; + if (t.IsGenericType) + typeToCheck = t.GetGenericTypeDefinition(); + if (typeToCheck == interfaceType) + yield return t; + } + yield break; + } + } + + interface IAotTest { + } + + [TestFixture] + // already done in Bug2096Test.cs -> [Preserve (AllMembers = true)] + public partial class AotBugsTest : IAotTest { + + // https://bugzilla.xamarin.com/show_bug.cgi?id=3285 + [Test] + public void Aot_3285 () + { + // called as an extension method (always worked) + Assert.False (GetType ().GetInterfaces (typeof (IExpectException)).Select (interf => interf != null).FirstOrDefault (), "false"); + + // workaround for #3285 - similar to previous fix for monotouch/aot + // called as a static method (does not change the result - but it was closer to the original test case) + Assert.True (AotExtension.GetInterfaces (GetType (), typeof (IAotTest)).Select (interf => interf != null).FirstOrDefault (delegate { return true; }), "delegate"); + + // actual, failing, test case (fixed by inlining code) + Assert.True (GetType ().GetInterfaces (typeof (IAotTest)).Select (interf => interf != null).FirstOrDefault (), "FirstOrDefault/true"); + + // other similar cases (returning bool with optional predicate delegate) + var enumerable = GetType ().GetInterfaces (typeof (IAotTest)).Select (interf => interf != null); + Assert.True (enumerable.Any (), "Any"); + Assert.True (enumerable.ElementAt (0), "ElementAt"); + Assert.True (enumerable.ElementAtOrDefault (0), "ElementAtOrDefault"); + Assert.True (enumerable.First (), "First"); + Assert.True (enumerable.Last (), "Last"); // failed before fix + Assert.True (enumerable.LastOrDefault (), "LastOrDefault"); // failed before fix + Assert.True (enumerable.Max (), "Max"); + Assert.True (enumerable.Min (), "Min"); + Assert.True (enumerable.Single (), "Single"); // failed before fix + Assert.True (enumerable.SingleOrDefault (), "SingleOrDefault"); // failed before fix + } + + [Test] + // https://bugzilla.xamarin.com/show_bug.cgi?id=3444 + public void ConcurrentDictionary_3444 () + { + // note: similar, but simpler, than the original bug report (same exception) + var cd = new ConcurrentDictionary (); + } + + class SomeObject { + public event EventHandler Event; + + public void RaiseEvent () + { + var fn = this.Event; + if (fn != null) + fn (this, EventArgs.Empty); + } + } + + void OnEvent (object sender, EventArgs e) + { + } + + [Test] + public void EventInfo_3682 () + { + var so = new SomeObject (); + + var e = so.GetType ().GetEvent ("Event"); + if (e != null) + e.AddEventHandler (so, new EventHandler (OnEvent)); + } + + [Test] + public void Workaround_3682 () + { + var so = new SomeObject (); + var e = so.GetType ().GetEvent ("Event"); + if (e != null) { + var add = e.GetAddMethod (); + add.Invoke (so, new object[] { new EventHandler(OnEvent) }); + } + } + + class Counseling { + public int FK_PERSON; + + public Counseling (int i) + { + FK_PERSON = i; + } + } + + class PersonDetail { + public int Id; + + public PersonDetail (int i) + { + Id = i; + } + } + + class CounselingWithPerson { + public Counseling Counseling { get; private set; } + public PersonDetail PersonDetail { get; private set; } + + public CounselingWithPerson (Counseling c, PersonDetail p) + { + Counseling = c; + PersonDetail = p; + } + } + + [Test] + public void Linq_Join_3627 () + { + List c = new List () { + new Counseling (1) + }; + List p = new List () { + new PersonDetail (1) + }; + var query = (from wqual in c + join personTable in p on wqual.FK_PERSON equals personTable.Id + select new CounselingWithPerson (wqual, personTable)); + Assert.NotNull (query.ToList ()); + // above throws ExecutionEngineException + } + + public void Workaround_3627 () + { + List c = new List () { + new Counseling (1) + }; + List p = new List () { + new PersonDetail (1) + }; + var query = (from wqual in c + join personTable in p on wqual.FK_PERSON.ToString () equals personTable.Id.ToString () + select new CounselingWithPerson (wqual, personTable)); + Assert.NotNull (query.ToList ()); + } + + public class Foo { + public int Id { get; set; } + public string Name { get; set; } + } + + [Test] + public void Linq () + { + var list = new List(); + list.Add (new Foo { Id = 3, Name="def"}); + list.Add (new Foo { Id = 2, Name="def"}); + list.Add (new Foo { Id = 1, Name="ggg"}); + var x = from l in list orderby l.Name, l.Id select l; + Assert.That (x.Count (), Is.EqualTo (3), "Count"); + // above throws ExecutionEngineException + } + + [Test] + public void Linq_Workaround () + { + var list = new List(); + list.Add (new Foo { Id = 3, Name="def"}); + list.Add (new Foo { Id = 2, Name="def"}); + list.Add (new Foo { Id = 1, Name="ggg"}); + var x = from l in list orderby l.Name, l.Id.ToString () descending select l; + } + + [Test] + public void SortDescending_3114 () + { + List list = new List () { + DateTime.Now, + DateTime.UtcNow + }; + var result = from datetime in list orderby datetime.Date, datetime.TimeOfDay descending select datetime; + // above throws ExecutionEngineException + // Attempting to JIT compile method 'System.Linq.OrderedEnumerable`1:CreateOrderedEnumerable (System.Func`2,System.Collections.Generic.IComparer`1,bool)' while running with --aot-only. + // .ToString hack does not help in this case :( so it looks even worse + } + + [Test] + public void Workaround_3114 () + { + List list = new List () { + DateTime.Now, + DateTime.UtcNow + }; + var result = from datetime in list orderby ((DateTime) datetime).Date.ToString (), ((DateTime) datetime).TimeOfDay.ToString () descending select (DateTime) datetime; + // Attempting to JIT compile method 'System.Linq.OrderedEnumerable`1:CreateOrderedEnumerable (System.Func`2,System.Collections.Generic.IComparer`1,bool)' while running with --aot-only. + Assert.That (result.Count (), Is.EqualTo (2), "Count"); + } + + [Test] + public void Any_3735 () + { + var array = new Environment.SpecialFolder [] { + Environment.SpecialFolder.ApplicationData, + Environment.SpecialFolder.CommonApplicationData + }; + Assert.True (array.Any (folder => folder == Environment.SpecialFolder.ApplicationData)); + // above throws ExecutionEngineException + // Attempting to JIT compile method '(wrapper managed-to-managed) System.Environment/SpecialFolder[]:System.Collections.Generic.IEnumerable`1.GetEnumerator ()' while running with --aot-only. + } + + [Test] + public void Workaround_3735 () + { + // note: we cannot use the same `enum` type in the workaround since it would make the + // AOT compiler add the code (and make the previous test case works) + List list = new List () { + MidpointRounding.AwayFromZero + }; + Assert.True (list.Any (rounding => rounding == MidpointRounding.AwayFromZero)); + } + + Task InnerTestB () + { + return Task.Factory.StartNew (() => default (T)).ContinueWith (t => true); + } + + [Test] + public void Continuation_2337 () + { + InnerTestB (); + if (Runtime.Arch == Arch.SIMULATOR) + Assert.Inconclusive ("only fails on devices"); + } + + // https://bugzilla.xamarin.com/show_bug.cgi?id=3902 + + class Question { + public bool Deleted { get; set; } + public bool IsAnswered { get; set; } + public int Position { get; set; } + public int SectionId { get; set; } + } + + class Section { + public int BoardId { get; set; } + public int Id { get; set; } + public int BulletinBoardId { get; set; } + public int Position { get; set; } + } + + List Table () where T : new () + { + List list = new List (); + for (int i=0; i < 5; i++) + list.Add (new T ()); + return list; + } + + [Test] + public void Linq_3902_c1 () + { + int boardId = 0; + var result = from q in Table () where q.Deleted == false + join s in Table
() on q.SectionId equals s.Id + where s.BoardId == boardId + orderby q.IsAnswered, s.Position, q.Position + select q; + // note: orderby causing: + // Attempting to JIT compile method 'System.Linq.OrderedEnumerable`1<<>__AnonType0`2>:CreateOrderedEnumerable (System.Func`2<<>__AnonType0`2, int>,System.Collections.Generic.IComparer`1,bool)' while running with --aot-only. + Assert.NotNull (result); + } + + [Test] + public void Workaround_3902_c1 () + { + int boardId = 0; + var result = from q in Table () where q.Deleted == false + join s in Table
() on q.SectionId equals s.Id + where s.BoardId == boardId + orderby q.IsAnswered.ToString (), s.Position.ToString (), q.Position.ToString () + select q; + Assert.NotNull (result); + } + + [Test] + public void Linq_3902_c4 () + { + int boardId = 0; + var results = from q in Table () where q.Deleted == false + join s in Table
() on q.SectionId equals s.Id + where s.BoardId == boardId + select q; + // query is ok + foreach (var result in results) + Assert.NotNull (result); + // accessing elements throws with: + // Attempting to JIT compile method 'System.Linq.Enumerable:m__5A (MonoTouchFixtures.AotBugsTest/Section)' while running with --aot-only. + if (Runtime.Arch == Arch.SIMULATOR) + Assert.Inconclusive ("only fails on devices"); + } + + [Test] + public void Workaround_3902_c4 () + { + int boardId = 0; + var results = from q in Table () where q.Deleted == false + join s in Table
() on q.SectionId.ToString () equals s.Id.ToString () + where s.BoardId == boardId + select q; + foreach (var result in results) + Assert.NotNull (result); + } + + public class VirtualGeneric { + public virtual ICollection MakeCollectionOfInputs (T input1, T input2, T input3) + { + Collection alist = new Collection (); + alist.Add (input1); + alist.Add (input2); + alist.Add (input3); + return alist; + } + } + + [Test] + public void Virtual_4114 () + { + VirtualGeneric g = new VirtualGeneric (); + Assert.NotNull (g.MakeCollectionOfInputs (1.0, 2.0, 3.0)); + } + + public class OverrideGeneric : VirtualGeneric { + public override ICollection MakeCollectionOfInputs (T input1, T input2, T input3) + { + Collection alist = new Collection (); + alist.Add (input1); + alist.Add (input2); + alist.Add (input3); + return alist; + } + } + + [Test] + public void Override_4114 () + { + OverrideGeneric g = new OverrideGeneric (); + // Attempting to JIT compile method 'MonoTouchFixtures.AotBugsTest/OverrideGeneric:MakeCollectionOfInputs (double,double,double)' while running with --aot-only. + g.MakeCollectionOfInputs (1.0, 2.0, 3.0); + if (Runtime.Arch == Arch.SIMULATOR) + Assert.Inconclusive ("only fails on devices"); + } + + public sealed class NewDictionary { + Dictionary _dictionary = new Dictionary (); + + public NewDictionary (IEnumerable> items) + { + ForEach (items, (item) => _dictionary.Add (item.Key, item.Value)); + } + + static void ForEach (IEnumerable collection, Action action) + { + if (collection != null) + foreach (T item in collection) + action (item); + } + } + + [Test] + public void ForEachKVP_4114 () + { + // Attempting to JIT compile method 'MonoTouchFixtures.AotBugsTest/NewDictionary`2:ForEach> (System.Collections.Generic.IEnumerable`1>,System.Action`1>)' while running with --aot-only. + new NewDictionary (null); + if (Runtime.Arch == Arch.SIMULATOR) + Assert.Inconclusive ("only fails on devices"); + } + + public class Enumbers { + public IEnumerable> Enumerate (List> alist) + { + return MakeEnumerable (alist.ToArray ()); + } + + IEnumerable> MakeEnumerable (KeyValuePair[] data) + { + return data.AsEnumerable (); + } + } + + [Test] + [ExpectedException (typeof (NullReferenceException))] + public void AsEnumerable_4114 () + { + Enumbers e = new Enumbers (); + // Attempting to JIT compile method 'System.Collections.Generic.List`1>:ToArray ()' while running with --aot-only. + e.Enumerate (null); + } + + static object mInstance = null; + + [MethodImpl(MethodImplOptions.Synchronized)] + public static object getInstance() { + if (mInstance == null) + mInstance = new object(); + return mInstance; + } + + // #9805 + [Test] + public void Synchronized () { + getInstance (); + } + + // https://bugzilla.xamarin.com/show_bug.cgi?id=8379 + + public class Base { + + public static List

CreateList

() + { + return new List

(); + } + + public static List StringList = CreateList (); + public static List IntList = CreateList (); + } + + public class Class1 : Base { + } + + [Test] + public void Bug8379_a () + { + new Base (); + } + + [Test] + public void Bug8379_b () + { + new Class1 (); + } + + [Test] + public void Bug5354 () + { + Action testAction = (string s) => { s.ToString (); }; + testAction.BeginInvoke ("Teszt", null, null); + } + + public static IEnumerable GetStringList() where T : struct, IConvertible + { + return Enum.GetValues(typeof(T)).Cast().Select(x=>x.ToString()); + } + + [Test] + public void Bug12811a () + { + int n = 1; + foreach (var e in GetStringList ()) { + Assert.NotNull (e, n.ToString ()); + n++; + } + } + + [Test] + public void Bug12811b () + { + int n = 1; + foreach (var e in Enum.GetValues (typeof (NSFileManagerItemReplacementOptions)).Cast ().Select (x=>x.ToString ())) { + Assert.NotNull (e, n.ToString ()); + n++; + } + } + + public enum MyEnum8ElementsInInt32 : int + { + Zero = 0 + , One = 1 + , Two = 2 + , Three = 3 + , Four = 4 + , Five = 5 + , Six = 6 + , Seven = 7 + } + + public enum MyEnum8ElementsInUInt32 : uint + { + Zero = 0 + , One = 1 + , Two = 2 + , Three = 3 + , Four = 4 + , Five = 5 + , Six = 6 + , Seven = 7 + } + + public enum MyEnum7ElementsInUInt16 : ushort + { + Zero = 0 + , One = 1 + , Two = 2 + , Three = 3 + , Four = 4 + , Five = 5 + , Six = 6 + } + + public enum MyEnum8ElementsInUInt16 : ushort + { + Zero = 0 + , One = 1 + , Two = 2 + , Three = 3 + , Four = 4 + , Five = 5 + , Six = 6 + , Seven = 7 + } + + [Test] + public void Bug12605 () + { + Assert.AreEqual ("One", Convert.ToString ((MyEnum8ElementsInInt32) 1), "1"); + Assert.AreEqual ("One", Convert.ToString ((MyEnum8ElementsInUInt32) 1), "2"); + Assert.AreEqual ("One", Convert.ToString ((MyEnum7ElementsInUInt16) 1), "3"); + Assert.AreEqual ("One", Convert.ToString ((MyEnum8ElementsInUInt16) 1), "4"); + } + + [Test] + public void Bug12895 () + { + var r = new System.Text.RegularExpressions.Regex (@"(?\G[ ]+)|(?\G? +)|(?\G[][{}:,])|(?\G[A-Za-z]+)|(?\G + \"" # Opening quote + (?: + \\u[0-9a-fA-F]{4} | # Unicode escape + \\b | \\f | \ | \ | \ | # Backspace, form-feed, newline, carriage-return, tab + \\\\ | \\/ | # Escaped backslash, slash + \\"" | # Escaped quotes + [^\p{Cc}\\""] # Any unicode character except a control code, a backslash or a double quote + )* # Zero of more of any of the previous classes + \"" # Closing quote + )|(?\G + -? # Optional minus + (?: + 0 | # Leading zero only allowed on its own (e.g. 0, 0.1, 0e1) + [1-9][0-9]* # Otherwise leading digit must be non-zero (so no 0123, 0001) + ) + (?:[.][0-9]*)? # Optional fraction + (?:[Ee][+-]?[0-9]+)? # Optional exponent + (?![A-Za-z0-9_]) # Must not be followed by an alphanumeric character + )", System.Text.RegularExpressions.RegexOptions.IgnorePatternWhitespace); + Assert.NotNull (r); // looking got EEE while executing, on devices, the above code + } + + [Test] + public void Bug26245 () + { + var c = new Collection (); + c.Add (new PointF (50, 50)); // crashed under ARM64 + Assert.That (c.Count, Is.EqualTo (1)); + } + + [Test] + public void Bug39443 () + { + // un-reproducible test case (added to have large pool of QA devices run iton different CPU) + var nfe = nfloat.Epsilon.ToString (); + if (IntPtr.Size == 4) { + Assert.That (float.Epsilon.ToString (), Is.EqualTo (nfe), "Epsilon"); + } else { + Assert.That (double.Epsilon.ToString (), Is.EqualTo (nfe), "Epsilon"); + } + } + } +} diff --git a/tests/linker-ios/link sdk/AppDelegate.cs b/tests/linker-ios/link sdk/AppDelegate.cs new file mode 100644 index 000000000000..6b6315b6c400 --- /dev/null +++ b/tests/linker-ios/link sdk/AppDelegate.cs @@ -0,0 +1,53 @@ + +#if !__WATCHOS__ + +using System; +using System.Collections.Generic; +using System.Reflection; +#if XAMCORE_2_0 +using Foundation; +using UIKit; +#else +using MonoTouch.Foundation; +using MonoTouch.UIKit; +#endif +using MonoTouch.NUnit.UI; + +namespace LinkSdk +{ + // The UIApplicationDelegate for the application. This class is responsible for launching the + // User Interface of the application, as well as listening (and optionally responding) to + // application events from iOS. + [Register ("AppDelegate")] + public partial class AppDelegate : UIApplicationDelegate + { + // class-level declarations + UIWindow window; + TouchRunner runner; + + // + // This method is invoked when the application has loaded and is ready to run. In this + // method you should instantiate the window, load the UI into it and then make the window + // visible. + // + // You have 17 seconds to return from this method, or iOS will terminate your application. + // + public override bool FinishedLaunching (UIApplication app, NSDictionary options) + { + // create a new window instance based on the screen size + window = new UIWindow (UIScreen.MainScreen.Bounds); + runner = new TouchRunner (window); + + // tests can be inside the main assembly + runner.Add (Assembly.GetExecutingAssembly ()); + runner.Add (typeof (BundledResources.ResourcesTest).Assembly); + + window.RootViewController = new UINavigationController (runner.GetViewController ()); + // make the window visible + window.MakeKeyAndVisible (); + + return true; + } + } +} +#endif // !__WATCHOS__ diff --git a/tests/linker-ios/link sdk/AsyncTest.cs b/tests/linker-ios/link sdk/AsyncTest.cs new file mode 100644 index 000000000000..9776afb5d8eb --- /dev/null +++ b/tests/linker-ios/link sdk/AsyncTest.cs @@ -0,0 +1,28 @@ +using System; +using System.Net.Http; +using System.Threading.Tasks; +#if XAMCORE_2_0 +using Foundation; +#else +using MonoTouch.Foundation; +#endif +using NUnit.Framework; + +namespace LinkSdk { + + [TestFixture] + [Preserve (AllMembers = true)] + public class AsyncTests { + + public Task LoadCategories () + { + return Task.Run (async () => await (new HttpClient ()).GetStringAsync ("http://google.com")); + } + + [Test] + public void Bug12221 () + { + LoadCategories ().Wait (); + } + } +} \ No newline at end of file diff --git a/tests/linker-ios/link sdk/Bug1820Test.cs b/tests/linker-ios/link sdk/Bug1820Test.cs new file mode 100644 index 000000000000..64062f527ef3 --- /dev/null +++ b/tests/linker-ios/link sdk/Bug1820Test.cs @@ -0,0 +1,177 @@ +using System; +using System.Collections.Generic; +using System.IO; +using System.Xml; +using System.Xml.Schema; +using System.Xml.Serialization; +#if XAMCORE_2_0 +using Foundation; +#else +using MonoTouch.Foundation; +#endif +using NUnit.Framework; + +namespace LinkSdk.Serialization { + + [TestFixture] + // we want the test to be availble if we use the linker + [Preserve (AllMembers = true)] + public partial class XmlSerializationTest { + + [Serializable] + [XmlType (AnonymousType = true)] + [XmlRoot (Namespace = "", IsNullable = false)] + public class Response { + private DataUpdates dataUpdatesField; + private static XmlSerializer serializer; + + public Response () + { + this.dataUpdatesField = new DataUpdates (); + } + + [XmlElement (Order = 0)] + public DataUpdates DataUpdates { + get { return this.dataUpdatesField; } + set { this.dataUpdatesField = value; } + } + + private static XmlSerializer Serializer { + get { + if ((serializer == null)) + serializer = new XmlSerializer (typeof (Response)); + return serializer; + } + } + + public static Response Deserialize (string xml) + { + StringReader stringReader = null; + try { + stringReader = new StringReader (xml); + return ((Response)(Serializer.Deserialize (XmlReader.Create (stringReader)))); + } finally { + if ((stringReader != null)) { + stringReader.Dispose (); + } + } + } + } + + [Serializable] + [XmlType (AnonymousType = true)] + [XmlRoot (Namespace = "", IsNullable = false)] + public class DataUpdates { + private List dataUpdateInfoField; + private static XmlSerializer serializer; + + public DataUpdates () + { + this.dataUpdateInfoField = new List (); + } + + // BUG1820 is here! remove Order = 0 and it works + [XmlElement ("DataUpdateInfo", Form = XmlSchemaForm.Unqualified, Order = 0)] + public List DataUpdateInfo { + get { return this.dataUpdateInfoField; } + set { this.dataUpdateInfoField = value; } + } + + private static XmlSerializer Serializer { + get { + if ((serializer == null)) + serializer = new XmlSerializer (typeof (DataUpdates)); + return serializer; + } + } + + public static DataUpdates Deserialize (string xml) + { + StringReader stringReader = null; + try { + stringReader = new StringReader (xml); + return ((DataUpdates)(Serializer.Deserialize (XmlReader.Create (stringReader)))); + } finally { + if ((stringReader != null)) { + stringReader.Dispose (); + } + } + } + } + + [Serializable] + [XmlType (AnonymousType = true)] + public class DataUpdatesDataUpdateInfo { + + private DateTime dataDateField; + private string dataTypeField; + private DateTime lastUpdatedDateField; + private static XmlSerializer serializer; + + public DataUpdatesDataUpdateInfo () + { + } + + [XmlAttribute] + public DateTime DataDate { + get { return this.dataDateField; } + set { this.dataDateField = value; } + } + + [XmlAttribute] + public string DataType { + get { return this.dataTypeField; } + set { this.dataTypeField = value; } + } + + [XmlAttribute] + public DateTime LastUpdatedDate { + get { return this.lastUpdatedDateField; } + set { this.lastUpdatedDateField = value; } + } + + private static XmlSerializer Serializer { + get { + if ((serializer == null)) + serializer = new XmlSerializer (typeof(DataUpdatesDataUpdateInfo)); + return serializer; + } + } + + public static DataUpdatesDataUpdateInfo Deserialize (string xml) + { + StringReader stringReader = null; + try { + stringReader = new StringReader (xml); + return ((DataUpdatesDataUpdateInfo)(Serializer.Deserialize (XmlReader.Create (stringReader)))); + } finally { + if ((stringReader != null)) { + stringReader.Dispose (); + } + } + } + } + + [Test] + // http://bugzilla.xamarin.com/show_bug.cgi?id=1820 + // note: this also test the linker (5.1+) ability not to remove 'unused' XML setters and .ctors used for serialization + public void Bug1820_GenericList () + { + string input = @" + + + + + + + + + ".Trim (); + Response r = Response.Deserialize (input); + Assert.That (r.DataUpdates.DataUpdateInfo.Count, Is.EqualTo (3), "Count"); + Assert.That (r.DataUpdates.DataUpdateInfo [0].DataDate.Day, Is.EqualTo (13), "0"); + Assert.That (r.DataUpdates.DataUpdateInfo [1].DataDate.Day, Is.EqualTo (14), "1"); + Assert.That (r.DataUpdates.DataUpdateInfo [2].DataDate.Day, Is.EqualTo (15), "2"); + } + } +} \ No newline at end of file diff --git a/tests/linker-ios/link sdk/Bug2096Test.cs b/tests/linker-ios/link sdk/Bug2096Test.cs new file mode 100644 index 000000000000..eecd05b4833b --- /dev/null +++ b/tests/linker-ios/link sdk/Bug2096Test.cs @@ -0,0 +1,58 @@ +using System; +#if XAMCORE_2_0 +using Foundation; +using ObjCRuntime; +#else +using MonoTouch.Foundation; +using MonoTouch.ObjCRuntime; +#endif +using NUnit.Framework; + +namespace LinkSdk.Aot { + + [TestFixture] + // we want the test to be availble if we use the linker + [Preserve (AllMembers = true)] + public partial class AotBugsTest { + + public struct VT { + public Action a; + } + + public class D { + } + + public class A { + public void OuterMethod (TArg1 value) + { + this.InnerMethod (value, 0); + } + + private void InnerMethod (TArg1 v1, TArg2 v2) + { + Console.WriteLine ("{0} {1}", v1, v2); + } + } + + [Test] + public void Bug2096_Aot () + { + var a = new A (); + + a.OuterMethod (1); + a.OuterMethod (DateTime.Now); + // works with 5.0.2 (5.1) + + var v = new VT (); + a.OuterMethod (v); + // works with 5.0.2 (5.1) + + var x = new D (); + a.OuterMethod (x); + // fails with 5.0.2 (5.1) when running on devices with + // Attempting to JIT compile method 'A:InnerMethod (D,long)' while running with --aot-only. + if (Runtime.Arch == Arch.SIMULATOR) + Assert.Inconclusive ("only fails on devices"); + } + } +} \ No newline at end of file diff --git a/tests/linker-ios/link sdk/CalendarTest.cs b/tests/linker-ios/link sdk/CalendarTest.cs new file mode 100644 index 000000000000..004bedc38662 --- /dev/null +++ b/tests/linker-ios/link sdk/CalendarTest.cs @@ -0,0 +1,42 @@ +// Copyright 2013 Xamarin Inc. All rights reserved. + +using System; +using System.Globalization; +#if XAMCORE_2_0 +using Foundation; +#else +using MonoTouch.Foundation; +#endif +using NUnit.Framework; + +namespace LinkSdk.Calendars { + + [TestFixture] + // we want the tests to be available because we use the linker + [Preserve (AllMembers = true)] + public class CalendarTest { + + // application must *NOT* be build with I18N.MidEast and I18N.Other (Thai) + + [Test] + public void UmAlQura () + { + var ci = CultureInfo.GetCultureInfo ("ar"); + Assert.That (ci.Calendar.ToString (), Is.EqualTo ("System.Globalization.GregorianCalendar"), "Calendar"); + } + + [Test] + public void Hijri () + { + var ci = CultureInfo.GetCultureInfo ("ps"); + Assert.That (ci.Calendar.ToString (), Is.EqualTo ("System.Globalization.GregorianCalendar"), "Calendar"); + } + + [Test] + public void ThaiBuddhist () + { + var ci = CultureInfo.GetCultureInfo ("th"); + Assert.That (ci.Calendar.ToString (), Is.EqualTo ("System.Globalization.GregorianCalendar"), "Calendar"); + } + } +} \ No newline at end of file diff --git a/tests/linker-ios/link sdk/CryptoTest.cs b/tests/linker-ios/link sdk/CryptoTest.cs new file mode 100644 index 000000000000..dcdd431ed3e4 --- /dev/null +++ b/tests/linker-ios/link sdk/CryptoTest.cs @@ -0,0 +1,218 @@ +// +// Cryptographic Unit Tests - for about everything that can go wrong wrt linking +// +// Authors: +// Sebastien Pouliot +// +// Copyright 2012 Xamarin Inc. +// + +using System; +using System.Net; +using System.Net.Security; +using System.Security.Cryptography; +using System.Security.Cryptography.X509Certificates; +#if XAMCORE_2_0 +using Foundation; +#else +using MonoTouch.Foundation; +#endif +using NUnit.Framework; + +namespace LinkSdk { + + [TestFixture] + // we want the test to be availble if we use the linker + [Preserve (AllMembers = true)] + public class CryptoTest { + + [Test] + public void AesCreate () + { + // Aes resides in mscorlib.dll but needs to create instance of types that are + // located inside System.Core.dll - IOW the linker needs to be aware of this + Aes aes = Aes.Create (); + Assert.NotNull (aes, "Aes"); + Assert.True (aes.GetType ().Assembly.FullName.StartsWith ("System.Core, ", StringComparison.Ordinal), "System.Core"); + } + + static int trust_validation_callback; + + [Test] + public void TrustUsingNewCallback () + { + // Three similar tests exists in dontlink, linkall and linksdk to test 3 different cases + // untrusted, custom ICertificatePolicy and ServerCertificateValidationCallback without + // having caching issues (in S.Net or the SSL handshake cache) + try { + ServicePointManager.ServerCertificateValidationCallback = delegate (object sender, X509Certificate cert, X509Chain chain, SslPolicyErrors errors) { + Assert.That (errors, Is.EqualTo (SslPolicyErrors.None), "certificateProblem"); + X509Certificate2 c2 = new X509Certificate2 (cert.GetRawCertData ()); + Assert.False (chain.Build (c2), "Build"); + Assert.AreSame (c2, chain.ChainElements [0].Certificate, "ChainElements"); + trust_validation_callback++; + return true; + }; + WebClient wc = new WebClient (); + Assert.IsNotNull (wc.DownloadString ("https://wrench.internalx.com/Wrench/Login.aspx")); + // caching means it will be called at least for the first run, but it might not + // be called again in subsequent requests (unless it expires) + Assert.That (trust_validation_callback, Is.GreaterThan (0), "validation done"); + } + finally { + ServicePointManager.ServerCertificateValidationCallback = null; + } + } + + [Test] + public void SSL_IP_5706 () + { + WebClient wc = new WebClient (); + // the certificate contains (several rules) the host name + Assert.NotNull (wc.DownloadString ("https://www.google.com")); + + // IP are (generally) not allowed + foreach (var ip in Dns.GetHostAddresses ("www.google.com")) { + if (ip.AddressFamily != System.Net.Sockets.AddressFamily.InterNetwork) + continue; + + Assert.Throws (delegate { + wc.DownloadString ("https://" + ip.ToString ()); + }, ip.ToString ()); + return; // checking a single IP is enough to prove the point + } + } + + static int sne_validation_callback; + + [Test] + public void TLS1_ServerNameExtension () + { + // without support for the "server_name" TLS extension (RFC3546) we receive the "general" + // certificate of a server, which might not be the right one if a single server instance + // is used for many hosts (without a common name) + + // note: SSLv3 won't work, test is inside linkall.app (due to result caching) + + var actual = ServicePointManager.SecurityProtocol; + try { + ServicePointManager.ServerCertificateValidationCallback = delegate (object sender, X509Certificate cert, X509Chain chain, SslPolicyErrors errors) { + Assert.That (errors, Is.EqualTo (SslPolicyErrors.None), "certificateProblem"); + X509Certificate2 c2 = new X509Certificate2 (cert.GetRawCertData ()); + Assert.False (chain.Build (c2), "Build"); + Assert.AreSame (c2, chain.ChainElements [0].Certificate, "ChainElements"); + sne_validation_callback++; + return true; + }; + ServicePointManager.SecurityProtocol = SecurityProtocolType.Tls; + WebClient wc = new WebClient (); + Assert.IsNotNull (wc.DownloadString ("https://api.imgur.com/2/stats")); + } + catch (WebException we) { + // failing to get data does not mean the SSL/TLS session was not established + if (sne_validation_callback == 0) { + // The remote server returned an error: (502) Bad Gateway. + // The remote server returned an error: (503) Service Unavailable. + if (we.Message.Contains ("(502)") || we.Message.Contains ("(503)")) + Assert.Inconclusive (we.Message); + throw; + } + } + finally { + ServicePointManager.ServerCertificateValidationCallback = null; + ServicePointManager.SecurityProtocol = actual; + // caching means it will be called at least for the first run, but it might not + // be called again in subsequent requests (unless it expires) + Assert.That (sne_validation_callback, Is.GreaterThan (0), "validation done"); + } + } + + [Test] + public void Chain () + { + X509Store store = new X509Store ("Trust"); + store.Open (OpenFlags.ReadWrite); + + string certString = "MIIDGjCCAgKgAwIBAgICApowDQYJKoZIhvcNAQEFBQAwLjELMAkGA1UEBhMCQ1oxDjAMBgNVBAoTBVJlYmV4MQ8wDQYDVQQDEwZUZXN0Q0EwHhcNMDAwMTAxMDAwMDAwWhcNNDkxMjMxMDAwMDAwWjAuMQswCQYDVQQGEwJDWjEOMAwGA1UEChMFUmViZXgxDzANBgNVBAMTBlRlc3RDQTCCASIwDQYJKoZIhvcNAQEBBQADggEPADCCAQoCggEBAMgeRAcaNLTFaaBhFx8RDJ8b9K655dNUXmO11mbImDbPq4qVeZXDgAjnzPov8iBscwfqBvBpF38LsxBIPA2i1d0RMsQruOhJHttA9I0enElUXXj63sOEVNMSQeg1IMyvNeEotag+Gcx6SF+HYnariublETaZGzwAOD2SM49mfqUyfkgeTjdO6qp8xnoEr7dS5pEBHDg70byj/JEeZd3gFea9TiOXhbCrI89dKeWYBeoHFYhhkaSB7q9EOaUEzKo/BQ6PBHFu6odfGkOjXuwfPkY/wUy9U4uj75LmdhzvJf6ifsJS9BQZF4//JcUYSxiyzpxDYqSbTF3g9w5Ds2LOAscCAwEAAaNCMEAwDgYDVR0PAQH/BAQDAgB/MA8GA1UdEwEB/wQFMAMBAf8wHQYDVR0OBBYEFD1v20tPgvHTEK/0eLO09j0rL2qXMA0GCSqGSIb3DQEBBQUAA4IBAQAZIjcdR3EZiFJ67gfCnPBrxVgFNvaRAMCYEYYIGDCAUeB4bLTu9dvun9KFhgVNqjgx+xTTpx9d/5mAZx5W3YAG6faQPCaHccLefB1M1hVPmo8md2uw1a44RHU9LlM0V5Lw8xTKRkQiZz3Ysu0sY27RvLrTptbbfkE4Rp9qAMguZT9cFrgPAzh+0zuo8NNj9Jz7/SSa83yIFmflCsHYSuNyKIy2iaX9TCVbTrwJmRIB65gqtTb6AKtFGIPzsb6nayHvgGHFchrFovcNrvRpE71F38oVG+eCjT23JfiIZim+yJLppSf56167u8etDcQ39j2b9kzWlHIVkVM0REpsKF7S"; + X509Certificate2 rootCert = new X509Certificate2 (Convert.FromBase64String (certString)); + if (!store.Certificates.Contains (rootCert)) + store.Add (rootCert); + + store.Close(); + + byte[] certData = new byte[] {0x30,0x82,0x02,0xFA,0x30,0x82,0x01,0xE2,0xA0,0x03,0x02,0x01,0x02,0x02,0x03,0x01,0x4F,0x55,0x30,0x0D,0x06,0x09,0x2A,0x86,0x48,0x86,0xF7,0x0D,0x01,0x01,0x05,0x05,0x00,0x30,0x2E,0x31,0x0B,0x30,0x09,0x06,0x03,0x55,0x04,0x06,0x13,0x02,0x43,0x5A,0x31,0x0E,0x30,0x0C,0x06,0x03,0x55,0x04,0x0A,0x13,0x05,0x52,0x65,0x62,0x65,0x78,0x31,0x0F,0x30,0x0D,0x06,0x03,0x55,0x04,0x03,0x13,0x06,0x54,0x65,0x73,0x74,0x43,0x41,0x30,0x1E,0x17,0x0D,0x31,0x32,0x30,0x34,0x32,0x32,0x31,0x38,0x33,0x31,0x35,0x33,0x5A,0x17,0x0D,0x34,0x39,0x31,0x32,0x33,0x31,0x30,0x30,0x30,0x30,0x30,0x30,0x5A,0x30,0x37,0x31,0x0B,0x30,0x09,0x06,0x03,0x55,0x04,0x06,0x13,0x02,0x43,0x5A,0x31,0x0E,0x30,0x0C,0x06,0x03,0x55,0x04,0x0A,0x13,0x05,0x52,0x65,0x62,0x65,0x78,0x31,0x18,0x30,0x16,0x06,0x03,0x55,0x04,0x03,0x13,0x0F,0x77,0x69,0x6E,0x30,0x31,0x2E,0x64,0x30,0x35,0x2E,0x6C,0x6F,0x63,0x61,0x6C,0x30,0x81,0x9F,0x30,0x0D,0x06,0x09,0x2A,0x86,0x48,0x86,0xF7,0x0D,0x01,0x01,0x01,0x05,0x00,0x03,0x81,0x8D,0x00,0x30,0x81,0x89,0x02,0x81,0x81,0x00,0xF1,0x4F,0xAC,0x71,0x70,0x8F,0x8A,0xFE,0x38,0x67,0xA7,0x21,0x56,0x8B,0x34,0xBC,0xF5,0xCD,0x48,0x1C,0x69,0xEB,0x83,0x98,0x69,0x3D,0x33,0x2A,0x7B,0x04,0xB1,0x0A,0xA9,0x2C,0x17,0xDD,0x41,0xEC,0x21,0x91,0xB8,0x12,0x95,0xB0,0x4C,0x2A,0x53,0xBF,0x06,0x47,0x72,0xBB,0x68,0xCA,0x49,0x34,0x15,0x7B,0x78,0x4F,0x42,0x03,0xD9,0x58,0xEE,0x9D,0x72,0x61,0xAD,0xAD,0x0C,0x28,0x65,0x61,0x48,0xF8,0x68,0xB5,0x16,0x19,0xD0,0xDD,0x47,0x44,0x86,0xE3,0xA6,0x93,0x81,0xD5,0xA1,0x70,0x23,0x05,0x74,0x33,0xD1,0xD2,0x21,0x17,0x68,0xAF,0x5F,0x25,0xD5,0x8C,0x72,0xF6,0x28,0xF4,0x1F,0x42,0x24,0xCF,0x18,0x7B,0x5D,0xCE,0x29,0x43,0xF2,0x10,0xB6,0x73,0x65,0x4C,0x0A,0x17,0x02,0x03,0x01,0x00,0x01,0xA3,0x81,0x9B,0x30,0x81,0x98,0x30,0x0E,0x06,0x03,0x55,0x1D,0x0F,0x01,0x01,0xFF,0x04,0x04,0x03,0x02,0x05,0xA0,0x30,0x1D,0x06,0x03,0x55,0x1D,0x0E,0x04,0x16,0x04,0x14,0x14,0x00,0x58,0x48,0x55,0x6C,0x45,0xC6,0xCC,0x06,0x25,0x2D,0xD3,0xBA,0x0C,0x08,0x81,0x00,0x58,0xDF,0x30,0x13,0x06,0x03,0x55,0x1D,0x25,0x04,0x0C,0x30,0x0A,0x06,0x08,0x2B,0x06,0x01,0x05,0x05,0x07,0x03,0x01,0x30,0x1F,0x06,0x03,0x55,0x1D,0x23,0x04,0x18,0x30,0x16,0x80,0x14,0x3D,0x6F,0xDB,0x4B,0x4F,0x82,0xF1,0xD3,0x10,0xAF,0xF4,0x78,0xB3,0xB4,0xF6,0x3D,0x2B,0x2F,0x6A,0x97,0x30,0x31,0x06,0x03,0x55,0x1D,0x1F,0x04,0x2A,0x30,0x28,0x30,0x26,0xA0,0x24,0xA0,0x22,0x86,0x20,0x68,0x74,0x74,0x70,0x3A,0x2F,0x2F,0x74,0x65,0x73,0x74,0x2D,0x63,0x61,0x2E,0x6C,0x6F,0x63,0x61,0x6C,0x2F,0x74,0x65,0x73,0x74,0x2D,0x63,0x61,0x2E,0x63,0x72,0x6C,0x30,0x0D,0x06,0x09,0x2A,0x86,0x48,0x86,0xF7,0x0D,0x01,0x01,0x05,0x05,0x00,0x03,0x82,0x01,0x01,0x00,0x22,0x48,0xC3,0x95,0x3A,0x51,0x72,0x15,0x41,0x5B,0x47,0xC4,0xC5,0x4E,0x2E,0x97,0xAC,0x1D,0x0B,0xD1,0xA4,0x38,0xF2,0xFB,0x6E,0x33,0x9D,0xC8,0x93,0x4C,0x88,0x34,0xA3,0x68,0xC7,0xC6,0x42,0x51,0x54,0x31,0x72,0x72,0xEB,0xEE,0x5C,0xF0,0x7D,0xC9,0xC8,0xAE,0x24,0x9F,0xA0,0x1D,0x2E,0xEE,0x84,0x55,0xC3,0x3A,0xC4,0xCE,0xE1,0xB3,0xA2,0xD2,0x1F,0x44,0xC8,0x81,0x0F,0x9C,0xED,0x5B,0x17,0xBB,0x2C,0xDA,0x4A,0x9D,0xF7,0x7D,0x5A,0x08,0x6C,0xA3,0xF4,0xCB,0x55,0xE6,0x1A,0xAA,0xC7,0x14,0x16,0x7D,0x46,0xD0,0x7C,0x71,0xA8,0xA7,0xEA,0xBF,0xA6,0x92,0xD4,0xC5,0x7A,0xB8,0x45,0x3A,0x00,0xB3,0xDC,0x76,0x2E,0xEB,0xB9,0xF4,0x6B,0xDC,0xF2,0xC4,0x7C,0x0C,0xD5,0x1C,0x73,0xE8,0xE1,0xBB,0xC1,0x5C,0xCC,0xD9,0xBE,0xDE,0x61,0x4D,0xEF,0x2B,0x23,0xFA,0xA6,0xF6,0xED,0x4F,0x5F,0x2C,0xCA,0x68,0x29,0x59,0x27,0x82,0x41,0x5E,0xAD,0xC8,0x93,0xBF,0x83,0x01,0x8F,0x32,0xCB,0x79,0xEE,0x93,0x4C,0xCB,0x87,0x48,0x62,0x0D,0x44,0xD7,0x80,0x31,0x87,0x41,0x72,0x2D,0x12,0xA0,0x2C,0x99,0x89,0x08,0x5F,0xE9,0xFE,0x5E,0xB4,0xEC,0xCB,0x6C,0x23,0xC1,0xB8,0xE4,0xD6,0x1E,0x4B,0x9C,0x88,0x0A,0x63,0x65,0x78,0xC0,0x37,0xAC,0x54,0xCB,0xDE,0xA9,0x0F,0x59,0x43,0x1E,0x41,0xF5,0x32,0xAC,0x85,0x69,0xE9,0xBA,0xA6,0x78,0x87,0x88,0x8B,0x71,0xFB,0xE4,0x51,0xC0,0xF5,0xB7,0x4C,0x1F,0xCF,0x6A,0x1C,0xF6,0x1B,0x27,0x50,0xE9,0xAC,0xBF,0xB7,0x4E}; + + X509Certificate2 cert = new X509Certificate2 (certData); + X509Chain chain = new X509Chain (false); + Assert.False (chain.Build (cert), "Online"); + + chain.ChainPolicy.RevocationMode = X509RevocationMode.Offline; + Assert.False (chain.Build (cert), "Offline"); + + chain.ChainPolicy.RevocationMode = X509RevocationMode.NoCheck; + Assert.True (chain.Build (cert), "NoCheck"); + } + + byte[] sha256_data = { + 0x2D, 0x2D, 0x2D, 0x2D, 0x2D, 0x42, 0x45, 0x47, 0x49, 0x4E, 0x20, 0x43, 0x45, 0x52, 0x54, 0x49, 0x46, 0x49, 0x43, 0x41, + 0x54, 0x45, 0x2D, 0x2D, 0x2D, 0x2D, 0x2D, 0x0D, 0x0A, 0x4D, 0x49, 0x49, 0x43, 0x78, 0x44, 0x43, 0x43, 0x41, 0x61, 0x79, + 0x67, 0x41, 0x77, 0x49, 0x42, 0x41, 0x67, 0x49, 0x44, 0x41, 0x4B, 0x37, 0x6C, 0x4D, 0x41, 0x30, 0x47, 0x43, 0x53, 0x71, + 0x47, 0x53, 0x49, 0x62, 0x33, 0x44, 0x51, 0x45, 0x42, 0x43, 0x77, 0x55, 0x41, 0x4D, 0x43, 0x34, 0x78, 0x43, 0x7A, 0x41, + 0x4A, 0x42, 0x67, 0x4E, 0x56, 0x42, 0x41, 0x59, 0x54, 0x41, 0x6B, 0x4E, 0x61, 0x0D, 0x0A, 0x4D, 0x51, 0x34, 0x77, 0x44, + 0x41, 0x59, 0x44, 0x56, 0x51, 0x51, 0x4B, 0x45, 0x77, 0x56, 0x53, 0x5A, 0x57, 0x4A, 0x6C, 0x65, 0x44, 0x45, 0x50, 0x4D, + 0x41, 0x30, 0x47, 0x41, 0x31, 0x55, 0x45, 0x41, 0x78, 0x4D, 0x47, 0x56, 0x47, 0x56, 0x7A, 0x64, 0x45, 0x4E, 0x42, 0x4D, + 0x42, 0x34, 0x58, 0x44, 0x54, 0x45, 0x7A, 0x4D, 0x44, 0x55, 0x78, 0x4F, 0x54, 0x45, 0x79, 0x4E, 0x44, 0x63, 0x31, 0x0D, + 0x0A, 0x4E, 0x31, 0x6F, 0x58, 0x44, 0x54, 0x51, 0x35, 0x4D, 0x54, 0x49, 0x7A, 0x4D, 0x54, 0x41, 0x77, 0x4D, 0x44, 0x41, + 0x77, 0x4D, 0x46, 0x6F, 0x77, 0x4F, 0x6A, 0x45, 0x57, 0x4D, 0x42, 0x51, 0x47, 0x41, 0x31, 0x55, 0x45, 0x41, 0x78, 0x4D, + 0x4E, 0x55, 0x6D, 0x56, 0x69, 0x5A, 0x58, 0x67, 0x67, 0x55, 0x33, 0x56, 0x77, 0x63, 0x47, 0x39, 0x79, 0x64, 0x44, 0x45, + 0x67, 0x4D, 0x42, 0x34, 0x47, 0x0D, 0x0A, 0x43, 0x53, 0x71, 0x47, 0x53, 0x49, 0x62, 0x33, 0x44, 0x51, 0x45, 0x4A, 0x41, + 0x52, 0x59, 0x52, 0x63, 0x33, 0x56, 0x77, 0x63, 0x47, 0x39, 0x79, 0x64, 0x45, 0x42, 0x79, 0x5A, 0x57, 0x4A, 0x6C, 0x65, + 0x43, 0x35, 0x75, 0x5A, 0x58, 0x51, 0x77, 0x67, 0x5A, 0x38, 0x77, 0x44, 0x51, 0x59, 0x4A, 0x4B, 0x6F, 0x5A, 0x49, 0x68, + 0x76, 0x63, 0x4E, 0x41, 0x51, 0x45, 0x42, 0x42, 0x51, 0x41, 0x44, 0x0D, 0x0A, 0x67, 0x59, 0x30, 0x41, 0x4D, 0x49, 0x47, + 0x4A, 0x41, 0x6F, 0x47, 0x42, 0x41, 0x4B, 0x7A, 0x36, 0x49, 0x37, 0x49, 0x59, 0x4E, 0x4A, 0x4C, 0x44, 0x43, 0x36, 0x42, + 0x79, 0x44, 0x32, 0x75, 0x59, 0x36, 0x69, 0x55, 0x61, 0x34, 0x30, 0x54, 0x34, 0x37, 0x34, 0x44, 0x41, 0x65, 0x59, 0x55, + 0x49, 0x31, 0x37, 0x43, 0x79, 0x39, 0x55, 0x6B, 0x77, 0x62, 0x4E, 0x4D, 0x2B, 0x6B, 0x39, 0x62, 0x57, 0x0D, 0x0A, 0x68, + 0x75, 0x46, 0x62, 0x65, 0x63, 0x56, 0x42, 0x6D, 0x43, 0x37, 0x42, 0x79, 0x31, 0x6C, 0x48, 0x65, 0x2B, 0x79, 0x41, 0x59, + 0x59, 0x78, 0x78, 0x74, 0x47, 0x50, 0x7A, 0x41, 0x48, 0x58, 0x50, 0x76, 0x68, 0x4A, 0x4D, 0x56, 0x50, 0x41, 0x2F, 0x37, + 0x4C, 0x36, 0x41, 0x4B, 0x58, 0x6D, 0x6A, 0x71, 0x69, 0x77, 0x78, 0x7A, 0x47, 0x51, 0x79, 0x30, 0x73, 0x59, 0x67, 0x2F, + 0x6A, 0x36, 0x79, 0x0D, 0x0A, 0x6F, 0x58, 0x39, 0x36, 0x39, 0x52, 0x53, 0x30, 0x49, 0x58, 0x33, 0x75, 0x33, 0x64, 0x31, + 0x72, 0x35, 0x61, 0x6F, 0x44, 0x76, 0x36, 0x4A, 0x58, 0x53, 0x69, 0x53, 0x73, 0x75, 0x67, 0x78, 0x56, 0x47, 0x69, 0x65, + 0x54, 0x53, 0x2F, 0x50, 0x71, 0x55, 0x6E, 0x6E, 0x76, 0x72, 0x49, 0x74, 0x59, 0x78, 0x6F, 0x64, 0x4F, 0x31, 0x58, 0x79, + 0x76, 0x41, 0x67, 0x4D, 0x42, 0x41, 0x41, 0x47, 0x6A, 0x0D, 0x0A, 0x59, 0x7A, 0x42, 0x68, 0x4D, 0x41, 0x34, 0x47, 0x41, + 0x31, 0x55, 0x64, 0x44, 0x77, 0x45, 0x42, 0x2F, 0x77, 0x51, 0x45, 0x41, 0x77, 0x49, 0x45, 0x38, 0x44, 0x41, 0x64, 0x42, + 0x67, 0x4E, 0x56, 0x48, 0x51, 0x34, 0x45, 0x46, 0x67, 0x51, 0x55, 0x66, 0x75, 0x52, 0x51, 0x78, 0x4E, 0x75, 0x59, 0x71, + 0x77, 0x73, 0x38, 0x56, 0x48, 0x7A, 0x4A, 0x6D, 0x4A, 0x50, 0x6F, 0x39, 0x41, 0x45, 0x6F, 0x0D, 0x0A, 0x6F, 0x50, 0x77, + 0x77, 0x44, 0x77, 0x59, 0x44, 0x56, 0x52, 0x30, 0x6C, 0x42, 0x41, 0x67, 0x77, 0x42, 0x67, 0x59, 0x45, 0x56, 0x52, 0x30, + 0x6C, 0x41, 0x44, 0x41, 0x66, 0x42, 0x67, 0x4E, 0x56, 0x48, 0x53, 0x4D, 0x45, 0x47, 0x44, 0x41, 0x57, 0x67, 0x42, 0x51, + 0x39, 0x62, 0x39, 0x74, 0x4C, 0x54, 0x34, 0x4C, 0x78, 0x30, 0x78, 0x43, 0x76, 0x39, 0x48, 0x69, 0x7A, 0x74, 0x50, 0x59, + 0x39, 0x0D, 0x0A, 0x4B, 0x79, 0x39, 0x71, 0x6C, 0x7A, 0x41, 0x4E, 0x42, 0x67, 0x6B, 0x71, 0x68, 0x6B, 0x69, 0x47, 0x39, + 0x77, 0x30, 0x42, 0x41, 0x51, 0x73, 0x46, 0x41, 0x41, 0x4F, 0x43, 0x41, 0x51, 0x45, 0x41, 0x41, 0x59, 0x62, 0x69, 0x46, + 0x41, 0x6D, 0x33, 0x6E, 0x71, 0x61, 0x6F, 0x4A, 0x51, 0x45, 0x41, 0x6D, 0x37, 0x7A, 0x34, 0x33, 0x71, 0x6E, 0x71, 0x41, + 0x6B, 0x41, 0x6E, 0x35, 0x30, 0x76, 0x6F, 0x0D, 0x0A, 0x75, 0x4F, 0x39, 0x4E, 0x57, 0x61, 0x33, 0x53, 0x43, 0x45, 0x38, + 0x78, 0x6B, 0x4C, 0x55, 0x2B, 0x31, 0x50, 0x62, 0x67, 0x76, 0x6F, 0x48, 0x4E, 0x50, 0x54, 0x6A, 0x36, 0x4D, 0x51, 0x30, + 0x59, 0x37, 0x6F, 0x63, 0x2B, 0x6D, 0x42, 0x75, 0x55, 0x6B, 0x5A, 0x52, 0x63, 0x4B, 0x33, 0x51, 0x4C, 0x69, 0x58, 0x6C, + 0x62, 0x34, 0x66, 0x6E, 0x7A, 0x39, 0x59, 0x55, 0x36, 0x66, 0x69, 0x7A, 0x4A, 0x0D, 0x0A, 0x79, 0x6A, 0x33, 0x76, 0x33, + 0x42, 0x34, 0x6B, 0x4A, 0x33, 0x5A, 0x62, 0x42, 0x6D, 0x38, 0x48, 0x4E, 0x34, 0x78, 0x79, 0x44, 0x62, 0x66, 0x6E, 0x77, + 0x6C, 0x67, 0x42, 0x55, 0x65, 0x6F, 0x68, 0x78, 0x61, 0x36, 0x2B, 0x50, 0x78, 0x67, 0x2F, 0x37, 0x72, 0x39, 0x34, 0x78, + 0x54, 0x4A, 0x72, 0x35, 0x46, 0x30, 0x43, 0x68, 0x2F, 0x41, 0x68, 0x2F, 0x6D, 0x59, 0x37, 0x66, 0x4B, 0x6C, 0x50, 0x0D, + 0x0A, 0x46, 0x46, 0x35, 0x47, 0x68, 0x4A, 0x2B, 0x62, 0x34, 0x76, 0x55, 0x6F, 0x36, 0x47, 0x74, 0x6E, 0x79, 0x6F, 0x4F, + 0x33, 0x58, 0x57, 0x4C, 0x45, 0x34, 0x4D, 0x38, 0x4B, 0x67, 0x68, 0x6C, 0x39, 0x78, 0x48, 0x4E, 0x32, 0x52, 0x76, 0x57, + 0x47, 0x45, 0x39, 0x4B, 0x6F, 0x31, 0x4B, 0x31, 0x55, 0x62, 0x42, 0x62, 0x53, 0x4A, 0x51, 0x4D, 0x76, 0x66, 0x65, 0x49, + 0x65, 0x52, 0x38, 0x32, 0x71, 0x0D, 0x0A, 0x69, 0x66, 0x37, 0x49, 0x30, 0x56, 0x2B, 0x77, 0x59, 0x70, 0x57, 0x61, 0x4B, + 0x79, 0x5A, 0x68, 0x33, 0x6C, 0x50, 0x4C, 0x34, 0x33, 0x67, 0x35, 0x4C, 0x4F, 0x42, 0x34, 0x75, 0x51, 0x6C, 0x68, 0x76, + 0x76, 0x50, 0x4D, 0x5A, 0x63, 0x43, 0x48, 0x36, 0x4F, 0x37, 0x37, 0x37, 0x6E, 0x2F, 0x33, 0x4C, 0x2B, 0x54, 0x6C, 0x32, + 0x2F, 0x41, 0x56, 0x31, 0x73, 0x7A, 0x73, 0x67, 0x53, 0x6B, 0x54, 0x0D, 0x0A, 0x47, 0x79, 0x74, 0x54, 0x75, 0x4B, 0x6A, + 0x51, 0x35, 0x6E, 0x50, 0x53, 0x58, 0x76, 0x65, 0x44, 0x39, 0x76, 0x4B, 0x42, 0x50, 0x2F, 0x58, 0x4C, 0x73, 0x54, 0x4D, + 0x75, 0x69, 0x6A, 0x48, 0x4C, 0x43, 0x68, 0x57, 0x55, 0x69, 0x33, 0x74, 0x4B, 0x7A, 0x49, 0x48, 0x6F, 0x66, 0x4B, 0x6F, + 0x58, 0x62, 0x42, 0x43, 0x35, 0x37, 0x77, 0x3D, 0x3D, 0x0D, 0x0A, 0x2D, 0x2D, 0x2D, 0x2D, 0x2D, 0x45, 0x4E, 0x44, 0x20, + 0x43, 0x45, 0x52, 0x54, 0x49, 0x46, 0x49, 0x43, 0x41, 0x54, 0x45, 0x2D, 0x2D, 0x2D, 0x2D, 0x2D, 0x0D, 0x0A, }; + + [Test] + public void Sha256 () + { + X509Certificate2 c = new X509Certificate2 (sha256_data); + // can't build is fine - as long as we do not throw + Assert.False (new X509Chain (false).Build (c), "Build"); + } + } +} diff --git a/tests/linker-ios/link sdk/DataContractTest.cs b/tests/linker-ios/link sdk/DataContractTest.cs new file mode 100644 index 000000000000..e76945d78fd7 --- /dev/null +++ b/tests/linker-ios/link sdk/DataContractTest.cs @@ -0,0 +1,48 @@ +using System; +using System.Collections.Generic; +using System.Runtime.Serialization; +#if XAMCORE_2_0 +using Foundation; +#else +using MonoTouch.Foundation; +#endif +using NUnit.Framework; + +namespace LinkSdk { + + [DataContract(Namespace="XamarinBugExample")] + public enum MyEnum : short + { + [EnumMember] + Foo = 0, + [EnumMember] + Bar = 1, + [EnumMember] + Baz = 2 + } + + [DataContract(Namespace="XamarinBugExample")] + public class MyClass + { + public MyClass() { } + + [DataMember] + List MyList { get; set; } + } + + [TestFixture] + // we want the test to be availble if we use the linker + [Preserve (AllMembers = true)] + public class CrashExample { + + [Test] + // http://forums.xamarin.com/discussion/7380/type-cast-error-in-xamarin-6-4-3-on-device-only#latest + // could not be reproduced with 6.4.4 + public void DoCrash() + { + System.Collections.IList lst = new List(); + object value = Enum.Parse (typeof(MyEnum), "1"); + lst.Add (value); // Exception here. List.cs throws ArgumentException. + } + } +} \ No newline at end of file diff --git a/tests/linker-ios/link sdk/DllImportTest.cs b/tests/linker-ios/link sdk/DllImportTest.cs new file mode 100644 index 000000000000..7569f209b9d7 --- /dev/null +++ b/tests/linker-ios/link sdk/DllImportTest.cs @@ -0,0 +1,77 @@ +// +// Unit tests for [DllImport] +// +// Authors: +// Sebastien Pouliot +// +// Copyright 2014-2015 Xamarin Inc. All rights reserved. +// + +using System; +using System.Net.NetworkInformation; +using System.Runtime.InteropServices; +#if XAMCORE_2_0 +using Foundation; +using ObjCRuntime; +#else +using MonoTouch; +using MonoTouch.Foundation; +using MonoTouch.ObjCRuntime; +#endif +using NUnit.Framework; + +namespace LinkSdk { + + [TestFixture] + [Preserve (AllMembers = true)] + public class DllImportTest { + + class NestedFirstLevel { + + public class NestedSecondLevel { + + [DllImport ("__Internal")] + public extern static string xamarin_get_locale_country_code (); + } + } + + [Test] + public void ScanForStrip_17327 () + { + // note: must be tested on a release (strip'ed) build + Assert.NotNull (NestedFirstLevel.NestedSecondLevel.xamarin_get_locale_country_code ()); + } + + [Test] + public void Sqlite3 () + { + var lib = Dlfcn.dlopen ("/usr/lib/libsqlite3.dylib", 0); + Assert.That (lib, Is.Not.EqualTo (IntPtr.Zero), "/usr/lib/libsqlite3.dylib"); + try { + Assert.That (Dlfcn.dlsym (lib, "sqlite3_bind_int"), Is.Not.EqualTo (IntPtr.Zero), "sqlite3_bind_int"); + // iOS does not have some symbols defined - if that change/fail in the future we'll need to update Mono.Data.Sqlite + Assert.That (Dlfcn.dlsym (lib, "sqlite3_key"), Is.EqualTo (IntPtr.Zero), "sqlite3_key"); + Assert.That (Dlfcn.dlsym (lib, "sqlite3_rekey"), Is.EqualTo (IntPtr.Zero), "sqlite3_rekey"); + Assert.That (Dlfcn.dlsym (lib, "sqlite3_column_database_name"), Is.EqualTo (IntPtr.Zero), "sqlite3_column_database_name"); + Assert.That (Dlfcn.dlsym (lib, "sqlite3_column_database_name16"), Is.EqualTo (IntPtr.Zero), "sqlite3_column_database_name16"); + Assert.That (Dlfcn.dlsym (lib, "sqlite3_column_origin_name"), Is.EqualTo (IntPtr.Zero), "sqlite3_column_origin_name"); + Assert.That (Dlfcn.dlsym (lib, "sqlite3_column_origin_name16"), Is.EqualTo (IntPtr.Zero), "sqlite3_column_origin_name16"); + Assert.That (Dlfcn.dlsym (lib, "sqlite3_column_table_name"), Is.EqualTo (IntPtr.Zero), "sqlite3_column_table_name"); + Assert.That (Dlfcn.dlsym (lib, "sqlite3_column_table_name16"), Is.EqualTo (IntPtr.Zero), "sqlite3_column_table_name16"); + } + finally { + Dlfcn.dlclose (lib); + } + } + + [Test] + public void LackOfCapget () + { + // OSX/iOS libc (libSystem.dylib) does not have a capget - which breaks dlsym=false (required for tvOS) + // iOS (tvOS/watchOS) does not support Process to run ping either so it ends up with a InvalidOperationException + // which is now "optimized" to reduce code size (and remove DllImport) until we implement ping (see: #964) + var p = new Ping (); + Assert.Throws (delegate { p.Send ("localhost"); }); + } + } +} \ No newline at end of file diff --git a/tests/linker-ios/link sdk/Info.plist b/tests/linker-ios/link sdk/Info.plist new file mode 100644 index 000000000000..63e5f235fd48 --- /dev/null +++ b/tests/linker-ios/link sdk/Info.plist @@ -0,0 +1,30 @@ + + + + + CFBundleDisplayName + LinkSdkTest + CFBundleIdentifier + com.xamarin.linksdk + UIDeviceFamily + + 1 + 2 + + UISupportedInterfaceOrientations + + UIInterfaceOrientationPortrait + UIInterfaceOrientationLandscapeLeft + UIInterfaceOrientationLandscapeRight + + UISupportedInterfaceOrientations~ipad + + UIInterfaceOrientationPortrait + UIInterfaceOrientationPortraitUpsideDown + UIInterfaceOrientationLandscapeLeft + UIInterfaceOrientationLandscapeRight + + MinimumOSVersion + 5.1.1 + + diff --git a/tests/linker-ios/link sdk/LinkExtraDefsTest.cs b/tests/linker-ios/link sdk/LinkExtraDefsTest.cs new file mode 100644 index 000000000000..fb00eb7d05da --- /dev/null +++ b/tests/linker-ios/link sdk/LinkExtraDefsTest.cs @@ -0,0 +1,65 @@ +// +// Unit tests for the mtouch's --xml linker option +// +// Authors: +// Sebastien Pouliot +// +// Copyright 2012 Xamarin Inc. All rights reserved. +// + +using System; +using System.Reflection; +#if XAMCORE_2_0 +using Foundation; +#else +using MonoTouch.Foundation; +#endif +using NUnit.Framework; + +namespace LinkSdk { + + [TestFixture] + [Preserve (AllMembers = true)] + public class LinkExtraDefsTest { + + // ensure the types in extra-linker-defs.xml are included + // even if they are: + // * part of SDK / product assemblies, where adding [Preserve] is not possible; + // * not used anywhere in this application + + // note: reflection is used so we're testing the XML-based preservation + // not the normal linking process + + [Test] + public void Corlib () + { + Type t = Type.GetType ("System.Security.HostSecurityManager, mscorlib"); + Assert.NotNull (t, "System.Security.HostSecurityManager"); + } + + [Test] + public void System () + { + Type t = Type.GetType ("System.Net.Mime.ContentType, System"); + Assert.NotNull (t, "System.Net.Mime.ContentType"); + // we asked for ParseValue to be preserved + Assert.NotNull (t.GetMethod ("ParseValue", BindingFlags.Instance | BindingFlags.NonPublic), "Parse"); + } + +#if !__WATCHOS__ + [Test] + public void MonoTouch () + { +#if XAMCORE_2_0 + Type t = Type.GetType ("CoreBluetooth.CBUUID, " + typeof(NSObject).Assembly.ToString ()); +#else + Type t = Type.GetType ("MonoTouch.CoreBluetooth.CBUUID, monotouch, Version=0.0.0.0, Culture=neutral, PublicKeyToken=null"); +#endif + Assert.NotNull (t, "[MonoTouch.]CoreBluetooth.CBUUID"); + // check (generated) fields since we instructed the linker to keep them + var f = t.GetFields (BindingFlags.NonPublic | BindingFlags.Static); + Assert.That (f.Length, Is.Not.EqualTo (0), "fields were preserved"); + } +#endif + } +} \ No newline at end of file diff --git a/tests/linker-ios/link sdk/LinkSdkRegressionTest.cs b/tests/linker-ios/link sdk/LinkSdkRegressionTest.cs new file mode 100644 index 000000000000..a8a13763efdd --- /dev/null +++ b/tests/linker-ios/link sdk/LinkSdkRegressionTest.cs @@ -0,0 +1,1047 @@ +using System; +using System.Collections.Generic; +using System.Collections.ObjectModel; +using System.ComponentModel; +using System.Data; +using System.Diagnostics; +using System.Globalization; +using System.IO; +using System.Json; +using System.Linq; +using System.Net; +using System.Net.NetworkInformation; +using System.Reflection; +using System.Runtime.CompilerServices; +using System.Runtime.InteropServices; +using System.Runtime.Serialization; +using System.Security.Permissions; +using System.Threading; +using System.Xml; +using Mono.Data.Sqlite; +using MonoTouch; +#if XAMCORE_2_0 +#if !__TVOS__ && !__WATCHOS__ +using AddressBook; +using AddressBookUI; +#endif +#if !__WATCHOS__ +using CoreAnimation; +#endif +using CoreData; +using CoreFoundation; +using Foundation; +using ObjCRuntime; +#if !__TVOS__ +using MapKit; +#endif +using UIKit; +#if !__WATCHOS__ +using OpenGLES; +#endif +#else +using MonoTouch; +using MonoTouch.AddressBook; +using MonoTouch.AddressBookUI; +using MonoTouch.CoreAnimation; +using MonoTouch.CoreData; +using MonoTouch.CoreFoundation; +using MonoTouch.Foundation; +using MonoTouch.ObjCRuntime; +using MonoTouch.MapKit; +using MonoTouch.UIKit; +using MonoTouch.OpenGLES; +#endif +using NUnit.Framework; + +namespace LinkSdk { + + [FileIOPermission (SecurityAction.LinkDemand, AllLocalFiles = FileIOPermissionAccess.AllAccess)] + public class SecurityDeclarationDecoratedUserCode { + + [FileIOPermission (SecurityAction.Assert, AllLocalFiles = FileIOPermissionAccess.NoAccess)] + static public bool Check () + { + return true; + } + } + + [TestFixture] + // we want the test to be availble if we use the linker + [Preserve (AllMembers = true)] + public class LinkSdkRegressionTest { + + [Test] + // https://github.com/xamarin/monotouch/commit/cbefbeaea2eda820dfc7214e976edc83a55df38e + public void MonoAssembly_LinkedOut () + { + Assembly a = Assembly.GetExecutingAssembly (); + Assert.That (a.GetType ().Name, Is.EqualTo ("MonoAssembly"), "MonoAssembly"); + } + + [Test] + // http://bugzilla.xamarin.com/show_bug.cgi?id=205 + // https://bugzilla.novell.com/show_bug.cgi?id=688414 + public void Bug205_ExposingIEnumerable () + { + var ds = new DataContractSerializer (typeof (IEnumerable)); + using (var xw = XmlWriter.Create (System.IO.Stream.Null)) + ds.WriteObject (xw, new int [] { 1, 2, 3 }); + // the above should not throw System.Runtime.Serialization.SerializationException + } + + [Test] + // http://bugzilla.xamarin.com/show_bug.cgi?id=233 + public void Bug233_MonoPInvokeCallback () + { + var c = new SqliteConnection ("Data Source=:memory:"); + c.Open (); + c.Update += (sender, e) => {}; + // the above should not crash + c.Close (); + } + + [Test] + // http://bugzilla.xamarin.com/show_bug.cgi?id=234 + public void Bug234_Interlocked () + { + string str = null; + Assert.Null (Interlocked.Exchange (ref str, "one"), "Exchange"); + // the above should not crash with System.ExecutionEngineException + Assert.That (str, Is.EqualTo ("one"), "one"); + } + + [Test] + // http://bugzilla.xamarin.com/show_bug.cgi?id=300 + // http://stackoverflow.com/questions/6517736/monotouch-crash-dictionary-firstordefault-type-initializer-predicateof + public void Bug300_Linker_PredicateOf () + { + Dictionary queued = new Dictionary (); + KeyValuePair valuePair = queued.FirstOrDefault (); + // above should not crash with System.ExecutionEngineException + Assert.NotNull (valuePair); + } + +#if !__WATCHOS__ + [Test] + // http://bugzilla.xamarin.com/show_bug.cgi?id=328 + public void Bug328_CompletionBlock () + { + CATransaction.Begin (); + CATransaction.CompletionBlock = delegate {}; + // the above should not crash with a MonoTouchException + CATransaction.Commit (); + } +#endif // !__WATCHOS__ + +#if !__TVOS__ && !__WATCHOS__ + [Test] + // http://bugzilla.xamarin.com/show_bug.cgi?id=769 + public void Bug769_UnregistredDelegate () + { + var tmp = Class.ThrowOnInitFailure; + Class.ThrowOnInitFailure = false; + try { + Assert.NotNull (new MKMapViewDelegate ()); + // the above should not throw an Exception + } finally { + Class.ThrowOnInitFailure = tmp; + } + } +#endif // !__TVOS__ && !__WATCHOS__ + +#if !__WATCHOS__ + [Test] + // http://bugzilla.xamarin.com/show_bug.cgi?id=865 + public void Bug865_CanOpenUrl () + { + Assert.False (UIApplication.SharedApplication.CanOpenUrl (null), "null"); + // the above should not throw an ArgumentNullException + // and that's important because NSUrl.FromString and NSUrl.ctor(string) differs + const string bad_tel = "tel://1800 023 009"; + Assert.Null (NSUrl.FromString (bad_tel), "bad url"); + // we now throw if `init*` fails + Assert.Throws (() => new NSUrl (bad_tel), "ctor, bad url"); + } +#endif // !__WATCHOS__ + + [Test] + // issue indirectly found when trying: http://bugzilla.xamarin.com/show_bug.cgi?id=928 + // similar to MonoAssembly_LinkedOut + // https://github.com/xamarin/monotouch/commit/409316f87f23723a384cb072163abd03ae7e6045 + public void Bug928_MonoModule_LinkedOut () + { + Module m = Assembly.GetExecutingAssembly ().ManifestModule; + Assert.That (m.GetType ().Name, Is.EqualTo ("MonoModule"), "MonoModule"); + } + +#if !__TVOS__ && !__WATCHOS__ + [Test] + // http://bugzilla.xamarin.com/show_bug.cgi?id=980 + public void Bug980_AddressBook_NRE () + { + using (ABPeoplePickerNavigationController picker = new ABPeoplePickerNavigationController ()) { + // no NRE should occur + if (UIDevice.CurrentDevice.CheckSystemVersion (8, 0)) + Assert.Null (picker.AddressBook); + else + Assert.NotNull (picker.AddressBook); + } + } + + [Test] + public void AddressBook_Constants () + { + // we want to ensure we can get the constants without authorization (on iOS 6.0+) so this application + // needs to be unauthorized (in settings.app). Note: authorization checks only occurs on devices + if ((Runtime.Arch == Arch.DEVICE) && UIDevice.CurrentDevice.CheckSystemVersion (6,0)) { + Assert.That (ABAddressBook.GetAuthorizationStatus (), Is.Not.EqualTo (ABAuthorizationStatus.Authorized), + "Please deny access to contacts for this this application (it's important for this test)"); + } + Assert.IsNotNull (ABPersonAddressKey.City, "ABPersonAddressKey"); + } +#endif // !__TVOS__ && !__WATCHOS__ + + [Test] + // http://bugzilla.xamarin.com/show_bug.cgi?id=1387 + public void Bug1387_UIEdgeInsets_ToString () + { + var insets = new UIEdgeInsets (1, 2, 3, 4); + Assert.False (insets.ToString ().Contains ("UIEdgeInsets")); + } + + void CheckExceptionDetailProperty (PropertyInfo pi) + { + bool data_member = true; + foreach (var ca in pi.GetCustomAttributes (false)) { + if (ca is DataMemberAttribute) { + data_member = true; + break; + } + } + // to be valid both getter and setter must be present if [DataMember] + if (data_member) { + Assert.NotNull (pi.GetGetMethod (true), "get_" + pi.Name); + Assert.NotNull (pi.GetSetMethod (true), "set_" + pi.Name); + } else { + // check well-known [DataMember] + switch (pi.Name) { + case "HelpLink": + case "InnerException": + case "Message": + case "StackTrace": + case "Type": + Assert.Fail ("{0} is missing it's [DataMember] attribute", pi.Name); + break; + } + } + } + + [Test] + // http://bugzilla.xamarin.com/show_bug.cgi?id=1415 + public void Bug1415_Linker_DataMember () + { + // the typeof ensure we're can't (totally) link away System.ServiceModel.dll + Type ed = typeof (System.ServiceModel.AuditLevel).Assembly.GetType ("System.ServiceModel.ExceptionDetail", false); + // which means it's [DataContract] / [DataMember] should not be linked out + // even if we're not specifically using them (and without [Preserve] being added) + // which is important since System.ServiceModel.dll is an SDK assembly + Assert.NotNull (ed, "ExceptionDetail"); + bool help_link = false; + bool inner_exception = false; + bool message = false; + bool stack_trace = false; + bool type = false; + foreach (var pi in ed.GetProperties ()) { + CheckExceptionDetailProperty (pi); + switch (pi.Name) { + case "HelpLink": + help_link = true; + break; + case "InnerException": + inner_exception = true; + break; + case "Message": + message = true; + break; + case "StackTrace": + stack_trace = true; + break; + case "Type": + type = true; + break; + } + } + // ensure all properties are still present + Assert.True (help_link, "HelpLink"); + Assert.True (inner_exception, "InnerException"); + Assert.True (message, "Message"); + Assert.True (stack_trace, "StackTrace"); + Assert.True (type, "Type"); + } + + [Test] + // http://bugzilla.xamarin.com/show_bug.cgi?id=1415 + // not really part of the bug - but part of the same fix + public void Bug1415_Linker_XmlAttribute () + { + // the typeof ensure we're can't (totally) link away System.ServiceModel.dll + Type ed = typeof (System.ServiceModel.AuditLevel).Assembly.GetType ("System.ServiceModel.EndpointAddress10", false); + // type is decorated with both [XmlSchemaProvider] and [XmlRoot] + Assert.NotNull (ed, "EndpointAddress10"); + +#if !__WATCHOS__ // FIXME: this needs to use a different type than OpenTK.Quaternion, so that the test can run on WatchOS as wells + var q = new OpenTK.Quaternion (); + Assert.Null (q.GetType ().GetProperty ("XYZ"), "XmlIgnore"); + // should be null if application is linked (won't be if "Don't link" is used) +#endif // !__WATCHOS__ + } + + [Test] + // http://bugzilla.xamarin.com/show_bug.cgi?id=1443 + public void Bug1443_Linq_Aot () + { + List list = new List (); + Dictionary dict = new Dictionary (); + list.AddRange (from kv in dict orderby kv.Key select kv.Value.ToString ()); + // should not throw an ExecutionEngineException on devices + } + +#if !__TVOS__ && !__WATCHOS__ + [Test] + // http://bugzilla.xamarin.com/show_bug.cgi?id=1516 + public void Bug1516_Appearance_Linker () + { + // iOS7, since DP3, validates ?some? appearance properties, e.g. + // Objective-C exception thrown. Name: NSInvalidArgumentException Reason: -setTintColor: is not allowed for use with the appearance proxy. Perhaps you want to use the barTintColor property. + // UINavigationBar.Appearance.TintColor = UIColor.FromRGB (238,234,222); + UINavigationBar.Appearance.SetTitleTextAttributes (new UITextAttributes () { + TextColor = UIColor.FromRGB (85, 108, 17), + TextShadowColor = UIColor.Clear + }); + // should not throw if the application is linked + } +#endif + + [Test] + // http://bugzilla.xamarin.com/show_bug.cgi?id=1790 + public void Bug1790_TimeZoneInfo_Local () + { + // the simulator has complete file access but the device won't have - i.e. we can't depend on it + Assert.That (File.Exists ("/etc/localtime"), Is.EqualTo (Runtime.Arch == Arch.SIMULATOR), "/etc/localtime"); + Assert.NotNull (TimeZoneInfo.Local, "Local"); + // should not throw a TimeZoneNotFoundException on devices + } + + [Test] + // http://bugzilla.xamarin.com/show_bug.cgi?id=1922 + public void Bug1922_PLinq_Aot () + { + const int size = 100; + Random random = new Random (); + int[] values = new int [size]; + int currentNumber = 0; + List numbers = new List (); + while (currentNumber < 100) { + values [currentNumber] = random.Next (1, 10); + numbers.Add (currentNumber); + currentNumber ++; + } + numbers.AsParallel ().ForAll (number => { + Thread.Sleep (values [number]); + //Console.WriteLine (number); + }); + if (Runtime.Arch == Arch.SIMULATOR) + Assert.Inconclusive ("only fails on devices"); + } + + [Test] + public void Bug2000_NSPersistentStoreCoordinator () + { + // from http://www.sgmunn.com/?p=1#comments + NSAttributeDescription description = new NSAttributeDescription (); + Assert.That (description.Handle, Is.Not.EqualTo (IntPtr.Zero), "NSAttributeDescription"); + description.AttributeType = NSAttributeType.Integer32; + description.Name = "SomeId"; + description.Optional = false; + + NSEntityDescription entity = new NSEntityDescription (); + Assert.That (entity.Handle, Is.Not.EqualTo (IntPtr.Zero), "NSEntityDescription"); + entity.Name = "TestEntity"; + entity.Properties = new NSPropertyDescription[1] { description }; + + NSManagedObjectModel model = new NSManagedObjectModel (); + Assert.That (model.Handle, Is.Not.EqualTo (IntPtr.Zero), "NSManagedObjectModel"); + model.Entities = new NSEntityDescription[1] { entity }; + model.SetEntities (model.Entities, String.Empty); + + NSUrl url = new NSUrl ("test.sqlite", false); + + // from http://bugzilla.xamarin.com/show_bug.cgi?id=2000 + NSError error; + var c = new NSPersistentStoreCoordinator (model); + c.AddPersistentStoreWithType (NSPersistentStoreCoordinator.SQLiteStoreType, null, url, null, out error); + Assert.True (Runtime.Arch == Arch.SIMULATOR ? error == null : error.Code == 512, "error"); + } + + [Test] + // http://lists.ximian.com/pipermail/monotouch/2011-December/006976.html + public void Linker_RuntimeWrappedException () + { + try { + // can't throw anything else but Exception-derived types from C# + support.throw_object (); + } + catch (Exception e) { + Assert.That (e.GetType ().Name, Is.EqualTo ("RuntimeWrappedException"), "RuntimeWrappedException"); + } + } + + [Test] + // http://stackoverflow.com/questions/8602726/cant-open-sqlite-database-in-read-only-mode + public void Sqlite_ReadOnly () + { + var c = new SqliteConnection ("Data Source=:memory:;Read Only=true"); + c.Open (); + // the above should not throw a 'misuse' exception + c.Close (); + } + + [Test] + public void AsQueryable_3028 () + { + string [] foos = new string [] { "hi", "bye" }; + string f = foos.AsQueryable ().First (); + Assert.That (f, Is.EqualTo ("hi"), "f"); + } + +#if !__WATCHOS__ + [Test] + public void OpenTk_3049 () + { + using (var gc1 = OpenTK.Platform.Utilities.CreateGraphicsContext (EAGLRenderingAPI.OpenGLES1)) { + Assert.NotNull (gc1); + } + using (var gc2 = OpenTK.Platform.Utilities.CreateGraphicsContext (EAGLRenderingAPI.OpenGLES2)) { + Assert.NotNull (gc2); + } + } + + [Test] + public void OpenTk_Preserved () + { +#if XAMCORE_2_0 + const string OpenTKAssembly = "OpenTK-1.0"; +#else + const string OpenTKAssembly = "OpenTK"; +#endif + var gl = Type.GetType ("OpenTK.Graphics.ES11.GL, " + OpenTKAssembly, false); + Assert.NotNull (gl, "ES11/GL"); + var core = Type.GetType ("OpenTK.Graphics.ES11.GL/Core, " + OpenTKAssembly, false); + Assert.NotNull (core, "ES11/Core"); + + gl = Type.GetType ("OpenTK.Graphics.ES20.GL, " + OpenTKAssembly, false); + Assert.NotNull (gl, "ES20/GL"); + core = Type.GetType ("OpenTK.Graphics.ES20.GL/Core, " + OpenTKAssembly, false); + Assert.NotNull (core, "ES20/Core"); + } +#endif // !__WATCHOS__ + + [Test] + public void XElement_3137 () + { + CultureInfo current = Thread.CurrentThread.CurrentCulture; + try { + Thread.CurrentThread.CurrentCulture = new CultureInfo ("en-US"); + var element1 = new System.Xml.Linq.XElement ("Property1", new System.Xml.Linq.XAttribute ("type", "number"), 1.2343445); + Assert.That (element1.ToString (), Is.EqualTo ("1.2343445"), "en-US"); + + Thread.CurrentThread.CurrentCulture = new System.Globalization.CultureInfo ("de-DE"); + // this was already working because the element was created with en-US + Assert.That (element1.ToString (), Is.EqualTo ("1.2343445"), "de-DE/1"); + // however creating a new, identical, element under de-DE return*ed* a different string + var element2 = new System.Xml.Linq.XElement ("Property1", new System.Xml.Linq.XAttribute ("type", "number"), 1.2343445); + Assert.That (element2.ToString (), Is.EqualTo ("1.2343445"), "de-DE/2"); + } + finally { + Thread.CurrentThread.CurrentCulture = current; + } + } + +#if !__TVOS__ && !__WATCHOS__ + [Test] + public void Modal_3489 () + { + using (UIViewController a = new UIViewController ()) + using (UIViewController b = new UIViewController ()) + using (UIViewController c = new UIViewController ()) { + a.PresentModalViewController (b, true); + b.PresentModalViewController (c, true); + +#if XAMCORE_2_0 + b.DismissModalViewController (true); + a.DismissModalViewController (true); //error +#else + b.DismissModalViewControllerAnimated (true); + a.DismissModalViewControllerAnimated (true); //error +#endif + } + } +#endif // !__TVOS__ && !__WATCHOS__ + + [Test] + public void TypeDescriptor_A7793 () + { + Assert.NotNull (TypeDescriptor.GetConverter (typeof (bool))); + } + + [Test] + public void Parse_3677 () + { + Assert.That (sbyte.Parse ("E3", NumberStyles.HexNumber), Is.EqualTo (-29), "SByte"); + Assert.That (short.Parse ("E3E3", NumberStyles.HexNumber), Is.EqualTo (-7197), "Int16"); + } + + public class DeviceHardware { + public const string HardwareProperty = "hw.machine"; + + public enum HardwareVersion { + iPhone, + iPhone3G, + iPhone3GS, + iPhone4, + iPod1G, + iPod2G, + iPod3G, + iPod4G, + iPad, + iPhoneSimulator, + iPhone4Simulator, + iPadSimulator, + Unknown + } + + // Changing the constant to "/usr/bin/libSystem.dylib" allows this P/Invoke to work on Mac OS X + // Using "hw.model" as property gives Macintosh model, "hw.machine" kernel arch (ppc, ppc64, i386, x86_64) + [DllImport (Constants.libSystemLibrary)] + internal static extern int sysctlbyname ([MarshalAs(UnmanagedType.LPStr)] string property, // name of the property + IntPtr output, // output + IntPtr oldLen, // IntPtr.Zero + IntPtr newp, // IntPtr.Zero + uint newlen // 0 + ); + + public static HardwareVersion Version { + get { + // get the length of the string that will be returned + var pLen = Marshal.AllocHGlobal(sizeof(int)); + sysctlbyname(DeviceHardware.HardwareProperty, IntPtr.Zero, pLen, IntPtr.Zero, 0); + + var length = Marshal.ReadInt32(pLen); + + // check to see if we got a length + if (length == 0) + { + Marshal.FreeHGlobal(pLen); + return HardwareVersion.Unknown; + } + + // get the hardware string + var pStr = Marshal.AllocHGlobal(length); + sysctlbyname(DeviceHardware.HardwareProperty, pStr, pLen, IntPtr.Zero, 0); + + // convert the native string into a C# string + var hardwareStr = Marshal.PtrToStringAnsi(pStr); + var ret = HardwareVersion.Unknown; + + // determine which hardware we are running + if (hardwareStr == "iPhone1,1") + ret = HardwareVersion.iPhone; + else if (hardwareStr == "iPhone1,2") + ret = HardwareVersion.iPhone3G; + else if (hardwareStr == "iPhone2,1") + ret = HardwareVersion.iPhone3GS; + else if (hardwareStr == "iPhone3,1") + ret = HardwareVersion.iPhone4; + else if (hardwareStr == "iPad1,1") + ret = HardwareVersion.iPad; + else if (hardwareStr == "iPod1,1") + ret = HardwareVersion.iPod1G; + else if (hardwareStr == "iPod2,1") + ret = HardwareVersion.iPod2G; + else if (hardwareStr == "iPod3,1") + ret = HardwareVersion.iPod3G; + else if (hardwareStr == "iPod4,1") + ret = HardwareVersion.iPod3G; + else if (hardwareStr == "i386" || hardwareStr == "x86_64") { +#if __WATCHOS__ + ret = HardwareVersion.Unknown; +#else + if (UIDevice.CurrentDevice.Model.Contains("iPhone")) + ret = UIScreen.MainScreen.Bounds.Height * UIScreen.MainScreen.Scale == 960 || UIScreen.MainScreen.Bounds.Width * UIScreen.MainScreen.Scale == 960 ? HardwareVersion.iPhone4Simulator : HardwareVersion.iPhoneSimulator; + else + ret = HardwareVersion.iPadSimulator; +#endif + } + else ret = HardwareVersion.Unknown; + + // cleanup + Marshal.FreeHGlobal(pLen); + Marshal.FreeHGlobal(pStr); + + return ret; + } + } + } + + [Test] + // http://stackoverflow.com/questions/9685134/monotouch-fatal-crash-once-deployed + // could not be duplicated on iPad2 (rolf), iPad1 (spouliot), iPodTouch4 (spouliot) + public void Hardware_SO () + { + Assert.NotNull (DeviceHardware.Version, "Hardware"); + } + + public class Location {} + + private static Location mInstance = null; + + [MethodImpl (MethodImplOptions.Synchronized)] + public static Location getInstance () + { + if (mInstance == null) + mInstance = new Location (); + return mInstance; + } + + [Test] + public void Synchronized_3904 () + { + // crash with LLVM + Assert.NotNull (getInstance (), "Location"); + } + + [Test] + [Culture ("en")] + public void Json_Parse_4415 () + { + var f = 4.25987E-06f; + // note: always use '.' see http://www.json.org/fatfree.html + var s = f.ToString (); + var v = JsonValue.Parse (s); + Assert.AreEqual (f, (float) v, "Parse Negative Exponent"); + f *= 10; + Assert.AreNotEqual (f, (float) v, "non-equal"); + } + + [Test] + [Culture ("en")] + public void ConvertToDouble_4620 () + { + // can't duplicate bug when using invarient culture + Assert.That (Convert.ToDouble ("0.0"), Is.EqualTo (0.0d)); + } + + [Test] + public void NetworkInterface_4631 () + { + Assert.NotNull (NetworkInterface.GetAllNetworkInterfaces ()); + } + + [Test] + public void WebClient_SSL_Leak () + { + WebClient wc = new WebClient (); + // note: needs to be executed under Instrument to verify it does not leak + string s = wc.DownloadString ("https://developers.google.com"); + Assert.NotNull (s); + } + +#if !__TVOS__ && !__WATCHOS__ + [Test] + public void WebProxy_Leak () + { + // note: needs to be executed under Instrument to verify it does not leak + Assert.NotNull (CFNetwork.GetSystemProxySettings (), "should not leak"); + } +#endif // !__TVOS__ && !__WATCHOS__ + + [Test] + // https://bugzilla.novell.com/show_bug.cgi?id=650402 + public void ForeignKey_650402 () + { + DataSet data = new DataSet (); + DataTable parent = new DataTable ("parent"); + DataColumn pk = parent.Columns.Add ("PK"); + DataTable child = new DataTable ("child"); + DataColumn fk = child.Columns.Add ("FK"); + + data.Tables.Add (parent); + data.Tables.Add (child); + data.Relations.Add (pk, fk); + + parent.Rows.Add ("value"); + child.Rows.Add ("value"); + data.AcceptChanges (); + child.Rows[0].Delete (); + parent.Rows[0][0] = "value2"; + + data.EnforceConstraints = false; + data.EnforceConstraints = true; + } + + [Test] + public void Pointer_5200 () + { + // ensure the linker did not remove the type, which is used by the runtime + Assert.NotNull (Type.GetType ("System.Reflection.Pointer, mscorlib")); + } + + [Test] + public void LockRecursionException_5311 () + { + Assert.Throws (delegate { throw new LockRecursionException (); }); + } + + class AddedInSilverlight5 : INotifyPropertyChanging { + public event PropertyChangingEventHandler PropertyChanging; + } + + [Test] + public void INotifyPropertyChanging_5337 () + { + new AddedInSilverlight5 ().PropertyChanging += delegate { }; + } + + [Test] + public void MonoIOStat_6118 () + { + string file = NSBundle.MainBundle.ExecutablePath; + DateTime c1 = File.GetCreationTime (file).ToUniversalTime (); + DateTime c2 = (DateTime) NSFileManager.DefaultManager.GetAttributes (file).CreationDate; + Assert.That ((c1 - c2).Seconds, Is.LessThan (30), "MonoIOStat"); + } + + [Test] + public void ObjectHandleCtor () + { + Type o = typeof (Object); + // this returns a new System.Runtime.Remoting.ObjectHandle which (was) linked away previously + Assert.NotNull (Activator.CreateInstance (o.Assembly.GetName ().Name, o.FullName), "ObjectHandle"); + } + + [Test] + public void AttributeUsageAttribute_Persistance () + { + Assert.IsFalse (Attribute.IsDefined (GetType (), typeof(SerializableAttribute))); + } + + [Test] + [ExpectedException (typeof (NotSupportedException))] + public void LinkedAway () + { + new System.Runtime.Remoting.RemotingException (); + } + + [Test] + public void ArrayClear_11184 () + { + byte[] key = new byte [16]; + for (int i = 0; i < key.Length; i++) + key [i] = (byte) (255 - i); + Array.Clear (key, 5, 11); + for (int i = 5; i < key.Length; i++) + Assert.That (key [i], Is.EqualTo (0), i.ToString ()); + } + + public class Demo_14493 { + public void Update (object o) + { + } + } + + [Test] + public void Action_14493 () + { + var Demo = new Demo_14493 (); + Action a = null; + a += Demo.Update; + a -= Demo.Update; // Crash here + } + + enum AnEnum { + First = 1, + Second = 2 + }; + + [Test] + public void AotGcMemmove_Crash_17284 () + { + var arr = new AnEnum [16]; + var c = new ReadOnlyCollection (arr); + Assert.False (c.Contains (AnEnum.First)); + } + + enum MyEnum { + AValue, + AnotherValue + } + + [Test] + public void Aot_Gsharedvt_21893 () + { + IList _myValues = new List { MyEnum.AValue }; + bool pleaseDontCrash = _myValues.Contains (MyEnum.AnotherValue); + Assert.False (pleaseDontCrash); + } + + [Test] + public void PrivateMemorySize64 () + { + // ref: https://bugzilla.xamarin.com/show_bug.cgi?id=21882 + var mem = System.Diagnostics.Process.GetCurrentProcess ().PrivateMemorySize64; + // the above used a mach call that iOS samdbox did *not* allow (sandbox) on device + // but has been fixed (different call) for the same PID + Assert.That (mem, Is.Not.EqualTo (0), "PrivateMemorySize64"); + } + + string TestFolder (Environment.SpecialFolder folder, bool supported = true, bool exists = true, bool readOnly = false) + { + var path = Environment.GetFolderPath (folder); + Assert.That (path.Length > 0, Is.EqualTo (supported), folder.ToString ()); + if (!supported) + return path; + + Assert.That (Directory.Exists (path), Is.EqualTo (exists), path); + if (!exists) + return path; + + string file = Path.Combine (path, "temp.txt"); + try { + File.WriteAllText (file, "mine"); + Assert.False (readOnly, "!readOnly " + folder); + } + catch { + Assert.True (readOnly, "readOnly " + folder); + } + finally { + File.Delete (file); + } + return path; + } + + [Test] + public void SpecialFolder () + { + // iOS8 changes the rules of the game + var fm = NSFileManager.DefaultManager; + var docs = fm.GetUrls (NSSearchPathDirectory.DocumentDirectory, NSSearchPathDomain.User) [0].Path; + var libs = fm.GetUrls (NSSearchPathDirectory.LibraryDirectory, NSSearchPathDomain.User) [0].Path; + + // note: this test is more interesting on devices because of the sandbox they have + bool device = Runtime.Arch == Arch.DEVICE; + + // some stuff we do not support (return String.Empty for the path) + TestFolder (Environment.SpecialFolder.Programs, supported: false); + TestFolder (Environment.SpecialFolder.Startup, supported: false); + TestFolder (Environment.SpecialFolder.Recent, supported: false); + TestFolder (Environment.SpecialFolder.SendTo, supported: false); + TestFolder (Environment.SpecialFolder.StartMenu, supported: false); + TestFolder (Environment.SpecialFolder.MyComputer, supported: false); + TestFolder (Environment.SpecialFolder.NetworkShortcuts, supported: false); + TestFolder (Environment.SpecialFolder.CommonStartMenu, supported: false); + TestFolder (Environment.SpecialFolder.CommonPrograms, supported: false); + TestFolder (Environment.SpecialFolder.CommonStartup, supported: false); + TestFolder (Environment.SpecialFolder.CommonDesktopDirectory, supported: false); + TestFolder (Environment.SpecialFolder.PrinterShortcuts, supported: false); + TestFolder (Environment.SpecialFolder.Cookies, supported: false); + TestFolder (Environment.SpecialFolder.History, supported: false); + TestFolder (Environment.SpecialFolder.Windows, supported: false); + TestFolder (Environment.SpecialFolder.System, supported: false); + TestFolder (Environment.SpecialFolder.SystemX86, supported: false); + TestFolder (Environment.SpecialFolder.ProgramFilesX86, supported: false); + TestFolder (Environment.SpecialFolder.CommonProgramFiles, supported: false); + TestFolder (Environment.SpecialFolder.CommonProgramFilesX86, supported: false); + TestFolder (Environment.SpecialFolder.CommonDocuments, supported: false); + TestFolder (Environment.SpecialFolder.CommonAdminTools, supported: false); + TestFolder (Environment.SpecialFolder.AdminTools, supported: false); + TestFolder (Environment.SpecialFolder.CommonMusic, supported: false); + TestFolder (Environment.SpecialFolder.CommonPictures, supported: false); + TestFolder (Environment.SpecialFolder.CommonVideos, supported: false); + TestFolder (Environment.SpecialFolder.LocalizedResources, supported: false); + TestFolder (Environment.SpecialFolder.CommonOemLinks, supported: false); + TestFolder (Environment.SpecialFolder.CDBurning, supported: false); + + // some stuff we return a value - but the directory does not exists + + var path = TestFolder (Environment.SpecialFolder.Desktop, exists: false); + + path = TestFolder (Environment.SpecialFolder.Favorites, exists: false); + + path = TestFolder (Environment.SpecialFolder.MyMusic, exists: false); + + path = TestFolder (Environment.SpecialFolder.MyVideos, exists: false); + + path = TestFolder (Environment.SpecialFolder.DesktopDirectory, exists: false); + + path = TestFolder (Environment.SpecialFolder.Fonts, exists: false); + + path = TestFolder (Environment.SpecialFolder.Templates, exists: false); + + path = TestFolder (Environment.SpecialFolder.MyPictures, exists: false); + + path = TestFolder (Environment.SpecialFolder.CommonTemplates, exists: false); + + // some stuff we return and are usable either as read-only + path = TestFolder (Environment.SpecialFolder.CommonApplicationData, readOnly: true); + Assert.That (path, Is.EqualTo ("/usr/share"), "path - CommonApplicationData"); + + // and the simulator is more lax + path = TestFolder (Environment.SpecialFolder.ProgramFiles, readOnly: device); + Assert.That (path, Is.EqualTo ("/Applications"), "path - ProgramFiles"); + + path = TestFolder (Environment.SpecialFolder.UserProfile, readOnly: device); + if (Runtime.Arch == Arch.DEVICE) { +#if __WATCHOS__ + Assert.True (path.StartsWith ("/private/var/mobile/Containers/Data/Application/", StringComparison.Ordinal), "Containers-ios8"); +#else + if (UIDevice.CurrentDevice.CheckSystemVersion (8, 0)) + Assert.True (path.StartsWith ("/private/var/mobile/Containers/Data/Application/", StringComparison.Ordinal), "Containers-ios8"); + else + Assert.True (path.StartsWith ("/private/var/mobile/Applications/", StringComparison.Ordinal), "pre-Containers"); +#endif + } + +#if !__WATCHOS__ + // tvOS (device sandbox) is more restricive than iOS as it limit access to more + // directories, mostly because they are not guaranteed to be preserved between executions + bool tvos = UIDevice.CurrentDevice.UserInterfaceIdiom == UIUserInterfaceIdiom.TV; + if (tvos) + docs = Path.Combine (libs, "Caches", "Documents"); +#else + bool tvos = false; +#endif + + // and some stuff is read/write + path = TestFolder (Environment.SpecialFolder.MyDocuments); + Assert.That (path, Is.EqualTo (docs), "path - MyDocuments"); + + path = TestFolder (Environment.SpecialFolder.ApplicationData); + Assert.That (path, Is.EqualTo (docs + "/.config"), "path - ApplicationData"); + + path = TestFolder (Environment.SpecialFolder.LocalApplicationData); + Assert.That (path, Is.EqualTo (docs), "path - LocalApplicationData"); + + path = TestFolder (Environment.SpecialFolder.InternetCache); + Assert.That (path, Is.EqualTo (libs + "/Caches"), "path - InternetCache"); + + // new: expose NSLibraryDirectory from Environment.GetFolder + path = TestFolder (Environment.SpecialFolder.Resources, readOnly: tvos && device); + Assert.True (path.EndsWith ("/Library", StringComparison.Ordinal), "Resources"); + } + +#if !__WATCHOS__ + [Test] + public void Events () + { + using (var tv = new UITextView ()) { + Assert.Null (tv.WeakDelegate, "none"); + // event on UITextView itself + tv.Ended += (object sender, EventArgs e) => {}; + + var t = tv.WeakDelegate.GetType (); + Assert.That (t.Name, Is.EqualTo ("_UITextViewDelegate"), "textview"); + + var fi = t.GetField ("editingEnded", BindingFlags.NonPublic | BindingFlags.Instance); + Assert.NotNull (fi, "editingEnded"); + var value = fi.GetValue (tv.WeakDelegate); + Assert.NotNull (value, "value"); + +#if XAMCORE_2_0 + // and on the UIScrollView defined one + tv.Scrolled += (object sender, EventArgs e) => {}; + // and the existing (initial field) is still set + fi = t.GetField ("editingEnded", BindingFlags.NonPublic | BindingFlags.Instance); + Assert.NotNull (fi, "editingEnded/scrollview"); +#else + // In Classic UITextView also defines a Scrolled event, so make sure we get the UIScrollView one. + ((UIScrollView) tv).Scrolled += (object sender, EventArgs e) => {}; + + t = tv.WeakDelegate.GetType (); + Assert.That (t.Name, Is.EqualTo ("_UIScrollViewDelegate"), "scrollview"); + + fi = t.GetField ("editingEnded", BindingFlags.NonPublic | BindingFlags.Instance); + Assert.Null (fi, "editingEnded/scrollview"); +#endif + } + } +#endif // !__WATCHOS__ + + [Test] + public void SecurityDeclaration () + { + // note: security declarations != custom attributes + // we ensure that we can create the type / call the code + Assert.True (SecurityDeclarationDecoratedUserCode.Check (), "call"); + // we ensure that both the permission and the flag are NOT part of the final/linked binary (link removes security declarations) + Assert.Null (Type.GetType ("System.Security.Permissions.FileIOPermissionAttribute, mscorlib"), "FileIOPermissionAttribute"); + Assert.Null (Type.GetType ("System.Security.Permissions.FileIOPermissionAccess, mscorlib"), "FileIOPermissionAccess"); + } + +#if !__WATCHOS__ + [Test] + public void UIButtonSubclass () + { + // ensure the linker keeps the .ctor(UIButtonType) around + using (var b = new UIButton (UIButtonType.Custom)) { + // https://trello.com/c/Nf2B8mIM/484-remove-debug-code-in-the-linker + var m = typeof (UIButton).GetMethod ("VerifyIsUIButton", BindingFlags.Instance | BindingFlags.NonPublic); +#if DEBUG + // kept in debug builds + Assert.NotNull (m, "VerifyIsUIButton"); +#else + // removed from release builds + Assert.Null (m, "VerifyIsUIButton"); +#endif + } + } + +#endif // !__WATCHOS__ + + [Test] + public void MonoRuntime34671 () + { + Assert.NotNull (Type.GetType ("Mono.Runtime"), "Mono.Runtime"); + } + + [Test] + public void TraceListeners36255 () + { + Trace.Close (); // here too + Assert.NotNull (Trace.Listeners, "C6 had a SecurityPermission call"); + } + + [Test] + public void TlsProvider_Apple () + { + var provider = Mono.Security.Interface.MonoTlsProviderFactory.GetProvider (); + Assert.NotNull (provider, "provider"); + Assert.That (provider.ID, Is.EqualTo (new Guid ("981af8af-a3a3-419a-9f01-a518e3a17c1c")), "correct provider"); + } + + [Test] + public void OldTlsProvider_LinkedOut () + { + // make test work for classic (monotouch) and unified (iOS, tvOS and watchOS) + var fqn = typeof (NSObject).AssemblyQualifiedName.Replace ("Foundation.NSObject", "Security.Tls.OldTlsProvider"); + Assert.Null (Type.GetType (fqn), "Should not be included"); + } + + [Test] + public void AppleTls_Default () + { + // make test work for classic (monotouch) and unified (iOS, tvOS and watchOS) + var fqn = typeof (NSObject).AssemblyQualifiedName.Replace ("Foundation.NSObject", "Security.Tls.AppleTlsProvider"); + Assert.NotNull (Type.GetType (fqn), "Should be included"); + } + } +} \ No newline at end of file diff --git a/tests/linker-ios/link sdk/LocaleTest.cs b/tests/linker-ios/link sdk/LocaleTest.cs new file mode 100644 index 000000000000..6ab488df758a --- /dev/null +++ b/tests/linker-ios/link sdk/LocaleTest.cs @@ -0,0 +1,54 @@ +// Copyright 2016 Xamarin Inc. All rights reserved. + +using System; +using System.Collections.Generic; +#if XAMCORE_2_0 +using Foundation; +#else +using MonoTouch.Foundation; +#endif +using NUnit.Framework; + +namespace LinkSdk { + + [TestFixture] + // we want the tests to be available because we use the linker + [Preserve (AllMembers = true)] + public class LocaleTest { + + [Test] + [SetCulture ("cs-CZ")] + public void CzechDictComparer () + { + DictComparer (); + } + + [Test] + [SetCulture ("en-US")] + public void EnglishDictComparer () + { + DictComparer (); + } + + [Test] + // runs with whatever the device / simulator is configured + public void DefaultDictComparer () + { + DictComparer (); + } + + void DictComparer () + { + var n1 = "SEARCHFIELDS"; + var n2 = "Searchfields"; + + Assert.True (string.Equals (n1, n2, StringComparison.OrdinalIgnoreCase), "string equality"); + + var dict = new Dictionary (StringComparer.OrdinalIgnoreCase); + dict [n1] = "test"; + + string result; + Assert.True (dict.TryGetValue (n2, out result), "dictionary value"); + } + } +} diff --git a/tests/linker-ios/link sdk/Main.cs b/tests/linker-ios/link sdk/Main.cs new file mode 100644 index 000000000000..c43621acb4e1 --- /dev/null +++ b/tests/linker-ios/link sdk/Main.cs @@ -0,0 +1,26 @@ +#if !__WATCHOS__ +using System; +using System.Collections.Generic; +using System.Linq; +#if XAMCORE_2_0 +using Foundation; +using UIKit; +#else +using MonoTouch.Foundation; +using MonoTouch.UIKit; +#endif + +namespace LinkSdk +{ + public class Application + { + // This is the main entry point of the application. + static void Main (string[] args) + { + // if you want to use a different Application Delegate class from "AppDelegate" + // you can specify it here. + UIApplication.Main (args, null, "AppDelegate"); + } + } +} +#endif // !__WATCHOS__ diff --git a/tests/linker-ios/link sdk/OptimizeGeneratedCodeTest.cs b/tests/linker-ios/link sdk/OptimizeGeneratedCodeTest.cs new file mode 100644 index 000000000000..d0015cb884a6 --- /dev/null +++ b/tests/linker-ios/link sdk/OptimizeGeneratedCodeTest.cs @@ -0,0 +1,223 @@ +// +// Unit tests for the linker's OptimizeGeneratedCodeSubStep +// +// Authors: +// Sebastien Pouliot +// +// Copyright 2012-2013, 2016 Xamarin Inc. All rights reserved. +// + +using System; +using System.IO; +using System.Reflection; +using System.Runtime.CompilerServices; +using System.Runtime.InteropServices; +#if !__WATCHOS__ +using System.Drawing; +#endif +#if XAMCORE_2_0 +using Foundation; +using ObjCRuntime; +using UIKit; +#else +using MonoTouch.Foundation; +using MonoTouch.ObjCRuntime; +using MonoTouch.UIKit; +#endif +using NUnit.Framework; + +#if XAMCORE_2_0 +using SizeF=CoreGraphics.CGSize; +using RectangleF=CoreGraphics.CGRect; +#endif + +namespace Linker.Shared { + + partial class NotPreserved { + +#if !__WATCHOS__ + public void Bug11452 () + { + var button = new UIButton (); + button.TouchCancel += delegate { + if (Runtime.Arch == Arch.SIMULATOR) { + // kaboom + } + }; + } +#endif // !__WATCHOS__ + } + + class NSNotPreserved : NSObject { +#if !__WATCHOS__ + public void Bug11452 () + { + var button = new UIButton (); + button.TouchCancel += delegate { + if (Runtime.Arch == Arch.SIMULATOR) { + // kaboom + } + }; + } +#endif // !__WATCHOS__ + } + + [TestFixture] + // we want the test to be availble if we use the linker + [Preserve (AllMembers = true)] + public class OptimizeGeneratedCodeTest { + + // tests related to IL re-writting inside OptimizeGeneratedCodeSubStep + + // note: the following tests don't really ensure the IL code is ok - + // the best way to be sure if decompiling and reviewing the IL. OTOH + // it's pretty likely to crash if the IL was badly rewritten so running + // them makes me feel better ;-) + +#if !__TVOS__ && !__WATCHOS__ + [Test] + public void IsNewRefcountEnabled () + { + using (UIWebView wv = new UIWebView ()) { + Assert.Null (wv.Request, "IsNewRefcountEnabled"); + } + } + + class MyUIWebViewDelegate : UIWebViewDelegate { + } + + [Test] + public void MarkDirty () + { + using (UIWebView wv = new UIWebView ()) + using (MyUIWebViewDelegate del = new MyUIWebViewDelegate ()) { + wv.WeakDelegate = del; + Assert.That (wv.WeakDelegate, Is.EqualTo (del), "MarkDirty"); + } + } + + // this has a (single) "if (Runtime.Arch == Arch.DEVICE)" condition + + [Test] + public void SingleRuntimeArchDevice () + { + SizeF empty = SizeF.Empty; + using (UIView v = new UIView ()) + using (UIFont font = UIFont.SystemFontOfSize (12f)) { + SizeF size = "MonoTouch".StringSize (font); + Assert.False (size.IsEmpty, "!Empty"); + } + } +#endif // !__TVOS__ + + // this has 2 "if (Runtime.Arch == Arch.DEVICE)" conditions separated + // by "if (IsDirectBinding)" so modifying IL is a bit more tricky - so + // testing this, linked on both the simulator and on device is important + +#if !__WATCHOS__ + [Test] + public void DoubleRuntimeArchDevice () + { + SizeF empty = SizeF.Empty; + using (UIView v = new UIView ()) { + Assert.True (v.SizeThatFits (empty).IsEmpty, "Empty"); + } + } +#endif // !__WATCHOS__ + + // some UIImage bindings are now decorated with [Autorelease] and that + // MUST be considered since it adds a try/finally for the C# using + + [Test] + public void Autorelease () + { + using (UIImage img = new UIImage ()) { + // those are the two UIImage instance methods decorated with [Autorelease] +#if !__TVOS__ + img.StretchableImage (10, 10); +#endif + img.CreateResizableImage (new UIEdgeInsets (1, 2, 3, 4)); + // note: return value is null for iOS7 (and was non-null before it) + // anyway we care about not crashing due to the linker optimizing the IL, not the return values + } + } + +#if !__WATCHOS__ + [Test] + public void AnonymousDelegate () + { + // anonymous delegates are decorated with [CompilerGenerated] attributes but must + // not be processed since the IL inside them is not compiler generated + new NotPreserved ().Bug11452 (); + + using (var ns = new NSNotPreserved ()) { + ns.Bug11452 (); + } + } +#endif // !__WATCHOS__ + +#if LINKALL + [Test] + // the two attributes below are required for the optimizing code to kick in. + [CompilerGenerated] + [Export ("dummy")] + public void IntPtrSizeOptimization () + { + // bug #21541. + Marshal.FreeHGlobal (Marshal.AllocHGlobal (IntPtr.Size)); + + if (IntPtr.Size == 8) { + Console.WriteLine (0x11111111); + } else { + Console.WriteLine (0x22222222); + } + + var arr = MethodInfo.GetCurrentMethod ().GetMethodBody ().GetILAsByteArray (); + if (arr.Length < 2) // single `ret` instruction is added by the stripper + Assert.Inconclusive ("IL was stripped from the assembly (release mode)"); + + bool contains11 = false; + bool contains22 = false; + for (int i = 0; i < arr.Length - 4; i++) { + contains11 |= arr [i] == 0x11 && arr [i + 1] == 0x11 && arr [i + 2] == 0x11 && arr [i + 3] == 0x11; + contains22 |= arr [i] == 0x22 && arr [i + 1] == 0x22 && arr [i + 2] == 0x22 && arr [i + 3] == 0x22; + + } + // the optimization is turned off in case of fat apps (32/64 bits) + bool b32 = Directory.Exists (Path.Combine (NSBundle.MainBundle.BundlePath, ".monotouch-32")); + bool b64 = Directory.Exists (Path.Combine (NSBundle.MainBundle.BundlePath, ".monotouch-64")); + // classic does not use the subdirectories, neither do we for single arch simulator + bool classic_or_sim = !b32 && !b64; + bool single_arch = !(b32 && b64); + if (classic_or_sim || single_arch) + Assert.IsFalse (contains11 && contains22, "neither instructions removed"); + // even if disabled this condition remains + Assert.IsFalse (!contains11 && !contains22, "both instructions removed"); + } + + [Test] + public void FinallyTest () + { + // bug #26415 + FinallyTestMethod (); + Assert.IsTrue (finally_invoked); + } + + bool finally_invoked; + [Export ("finallyTestMethod")] + [CompilerGenerated] + public IntPtr FinallyTestMethod () + { + try { + if (IntPtr.Size == 8) { + return IntPtr.Zero; + } else { + return IntPtr.Zero; + } + } finally { + finally_invoked = true; + } + } +#endif + } +} \ No newline at end of file diff --git a/tests/linker-ios/link sdk/PclTest.cs b/tests/linker-ios/link sdk/PclTest.cs new file mode 100644 index 000000000000..afbc354dd092 --- /dev/null +++ b/tests/linker-ios/link sdk/PclTest.cs @@ -0,0 +1,122 @@ +using System; +using System.IO; +using System.Net; +using System.ServiceModel; +using System.ServiceModel.Channels; +using System.Windows.Input; +using System.Xml; +#if XAMCORE_2_0 +using Foundation; +using ObjCRuntime; +#else +using MonoTouch.Foundation; +#endif +using NUnit.Framework; + +namespace LinkSdk { + + [TestFixture] + [Preserve (AllMembers = true)] + public class PclTest { + + [Test] + public void Corlib () + { + BinaryWriter bw = new BinaryWriter (Stream.Null); + bw.Dispose (); + } + + [Test] + public void System () + { + const string url = "http://www.google.com"; + Uri uri = new Uri (url); + + Assert.False (this is ICommand, "ICommand"); + + HttpWebRequest hwr = new HttpWebRequest (uri); + try { + Assert.True (hwr.SupportsCookieContainer, "SupportsCookieContainer"); + } + catch (NotImplementedException) { + // feature is not available, but the symbol itself is needed + } + + WebResponse wr = hwr.GetResponse (); + try { + Assert.True (wr.SupportsHeaders, "SupportsHeaders"); + } + catch (NotImplementedException) { + // feature is not available, but the symbol itself is needed + } + wr.Dispose (); + + try { + Assert.NotNull (WebRequest.CreateHttp (url)); + } + catch (NotImplementedException) { + // feature is not available, but the symbol itself is needed + } + + try { + Assert.NotNull (WebRequest.CreateHttp (uri)); + } + catch (NotImplementedException) { + // feature is not available, but the symbol itself is needed + } + } + + [Test] + public void ServiceModel () + { + AddressHeaderCollection ahc = new AddressHeaderCollection (); + try { + ahc.FindAll (null, null); + } + catch (NotImplementedException) { + // feature is not available, but the symbol itself is needed + } + + try { + FaultException.CreateFault (null, String.Empty, null); + } + catch (NotImplementedException) { + // feature is not available, but the symbol itself is needed + } + } + + [Test] + public void Xml () + { + try { + XmlConvert.VerifyPublicId (String.Empty); + } + catch (NotImplementedException) { + // feature is not available, but the symbol itself is needed + } + + try { + XmlConvert.VerifyWhitespace (String.Empty); + } + catch (NotImplementedException) { + // feature is not available, but the symbol itself is needed + } + + try { + XmlConvert.VerifyXmlChars (String.Empty); + } + catch (NotImplementedException) { + // feature is not available, but the symbol itself is needed + } + + var xr = XmlReader.Create (Stream.Null); + xr.Dispose (); + + var xw = XmlWriter.Create (Stream.Null); + xw.Dispose (); + + XmlReaderSettings xrs = new XmlReaderSettings (); + xrs.DtdProcessing = DtdProcessing.Ignore; + } + } +} \ No newline at end of file diff --git a/tests/linker-ios/link sdk/ReflectionTest.cs b/tests/linker-ios/link sdk/ReflectionTest.cs new file mode 100644 index 000000000000..fcd12a29921f --- /dev/null +++ b/tests/linker-ios/link sdk/ReflectionTest.cs @@ -0,0 +1,43 @@ +// Copyright 2016 Xamarin Inc. All rights reserved. + +using System; +using System.Reflection; +#if XAMCORE_2_0 +using Foundation; +#else +using MonoTouch.Foundation; +#endif +using NUnit.Framework; + +namespace Linker.Shared.Reflection { + + [TestFixture] + // we want the tests to be available because we use the linker + [Preserve (AllMembers = true)] + public class ReflectionTest { + + public void MethodWithParameters (string firstParameter, int secondParameter) + { + } + + [Test] + public void ParameterInfoName () + { + // linker will disable the metadata removal optimization if that property is used by user code + // however it's used inside mscorlib.dll (and SDK) so it cannot be checked while testing + //Assert.Null (typeof (ParameterInfo).GetProperty ("Name"), "Name"); + + var mi = this.GetType ().GetMethod ("MethodWithParameters"); + var p = mi.GetParameters (); +#if DEBUG || !LINKALL + // this optimization is only applied for release builds (not debug ones) + // link sdk won't touch this assembly (user code) so the parameters will be available + Assert.That (p [0].ToString (), Is.EqualTo ("System.String firstParameter"), "1"); + Assert.That (p [1].ToString (), Is.EqualTo ("Int32 secondParameter"), "2"); +#else + Assert.That (p [0].ToString (), Is.EqualTo ("System.String "), "1"); + Assert.That (p [1].ToString (), Is.EqualTo ("Int32 "), "2"); +#endif + } + } +} diff --git a/tests/linker-ios/link sdk/TaskTest.cs b/tests/linker-ios/link sdk/TaskTest.cs new file mode 100644 index 000000000000..8c6ef7ca7c75 --- /dev/null +++ b/tests/linker-ios/link sdk/TaskTest.cs @@ -0,0 +1,61 @@ +using System; +using System.Collections.Generic; +using System.Collections.Concurrent; +using System.Threading; +using System.Threading.Tasks; +#if XAMCORE_2_0 +using Foundation; +using ObjCRuntime; +#else +using MonoTouch.Foundation; +#endif +using NUnit.Framework; + +namespace LinkSdk { + + [TestFixture] + [Preserve (AllMembers = true)] + public class TaskBugsTest { + + [Test] + public void ContinueWithDifferentOptionsAreCanceledTest () + { + TaskScheduler.UnobservedTaskException += (obj, evt) => evt.SetObserved (); + var mre = new ManualResetEventSlim (); + var task = Task.Factory.StartNew (() => mre.Wait (200)); + var contFailed = task.ContinueWith (t => {}, TaskContinuationOptions.OnlyOnFaulted); + var contCanceled = task.ContinueWith (t => {}, TaskContinuationOptions.OnlyOnCanceled); + var contSuccess = task.ContinueWith (t => {}, TaskContinuationOptions.OnlyOnRanToCompletion); + + mre.Set (); + contSuccess.Wait (100); + + Assert.True (contSuccess.IsCompleted, "contSuccess.IsCompleted"); + Assert.True (contFailed.IsCompleted, "contFailed.IsCompleted"); + Assert.True (contCanceled.IsCompleted, "contCanceled.IsCompleted"); + Assert.False (contSuccess.IsCanceled, "contSuccess.IsCanceled"); + Assert.True (contFailed.IsCanceled, "contFailed.IsCanceled"); + Assert.True (contCanceled.IsCanceled, "contCanceled.IsCanceled"); + } + + [Test] + public void ContinueWhenAll_WithMixedCompletionState () + { + TaskScheduler.UnobservedTaskException += (obj, evt) => evt.SetObserved (); + var mre = new ManualResetEventSlim (); + var task = Task.Factory.StartNew (() => mre.Wait (200)); + var contFailed = task.ContinueWith (t => {}, TaskContinuationOptions.OnlyOnFaulted); + var contCanceled = task.ContinueWith (t => {}, TaskContinuationOptions.OnlyOnCanceled); + var contSuccess = task.ContinueWith (t => {}, TaskContinuationOptions.OnlyOnRanToCompletion); + bool ran = false; + + var cont = Task.Factory.ContinueWhenAll (new Task[] { contFailed, contCanceled, contSuccess }, _ => ran = true); + + mre.Set (); + cont.Wait (200); + + Assert.True (ran, "ran"); + Assert.That (cont.Status, Is.EqualTo (TaskStatus.RanToCompletion), "Status"); + } + } +} \ No newline at end of file diff --git a/tests/linker-ios/link sdk/extra-linker-defs-tvos.xml b/tests/linker-ios/link sdk/extra-linker-defs-tvos.xml new file mode 100644 index 000000000000..f21bf88c53f0 --- /dev/null +++ b/tests/linker-ios/link sdk/extra-linker-defs-tvos.xml @@ -0,0 +1,14 @@ + + + + + + + + + + + + + + \ No newline at end of file diff --git a/tests/linker-ios/link sdk/extra-linker-defs-unified.xml b/tests/linker-ios/link sdk/extra-linker-defs-unified.xml new file mode 100644 index 000000000000..e45255620cdb --- /dev/null +++ b/tests/linker-ios/link sdk/extra-linker-defs-unified.xml @@ -0,0 +1,14 @@ + + + + + + + + + + + + + + \ No newline at end of file diff --git a/tests/linker-ios/link sdk/extra-linker-defs-watchos.xml b/tests/linker-ios/link sdk/extra-linker-defs-watchos.xml new file mode 100644 index 000000000000..0e8a78f7adfd --- /dev/null +++ b/tests/linker-ios/link sdk/extra-linker-defs-watchos.xml @@ -0,0 +1,14 @@ + + + + + + + + + + + + + + \ No newline at end of file diff --git a/tests/linker-ios/link sdk/extra-linker-defs.xml b/tests/linker-ios/link sdk/extra-linker-defs.xml new file mode 100644 index 000000000000..f102f5906ae5 --- /dev/null +++ b/tests/linker-ios/link sdk/extra-linker-defs.xml @@ -0,0 +1,14 @@ + + + + + + + + + + + + + + \ No newline at end of file diff --git a/tests/linker-ios/link sdk/link sdk.csproj b/tests/linker-ios/link sdk/link sdk.csproj new file mode 100644 index 000000000000..a8f92b268973 --- /dev/null +++ b/tests/linker-ios/link sdk/link sdk.csproj @@ -0,0 +1,123 @@ + + + + Debug + iPhoneSimulator + 8.0.30703 + 2.0 + {C47F8F72-A7CA-4149-AA7D-BC4814803EF3} + {6BC8ED88-2882-458C-8E55-DFD12B67127B};{FAE04EC0-301F-11D3-BF4B-00C04F79EFBC} + Exe + linksdk + link sdk + MonoTouch + + + True + full + False + bin\iPhoneSimulator\Debug + __MOBILE__;__IOS__;DEBUG; + prompt + 4 + False + True + + + -v -v -disable-thread-check -xml=${ProjectDir}/extra-linker-defs.xml + i386 + + + none + False + bin\iPhoneSimulator\Release + prompt + 4 + False + -v -v -xml=${ProjectDir}/extra-linker-defs.xml + + + i386 + __MOBILE__;__IOS__;DO_NOT_REMOVE; + + + True + full + False + bin\iPhone\Debug + DEBUG;XAMARIN_APPLETLS; + prompt + 4 + False + True + iPhone Developer + -v -v -xml=${ProjectDir}/extra-linker-defs.xml "--dlsym:-link sdk" -gcc_flags="-UhoItsB0rken" + True + ARMv7 + true + + + none + False + bin\iPhone\Release + prompt + 4 + False + iPhone Developer + -v -v -xml=${ProjectDir}/extra-linker-defs.xml "--dlsym:-link sdk" + True + ARMv7 + + + DO_NOT_REMOVE;XAMARIN_APPLETLS; + + + + + + + + + + + + support.dll + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + {FE6EDEE9-ADF6-4F42-BCF2-B68C0A44EC3D} + BundledResources + + + + \ No newline at end of file diff --git a/tests/linker-ios/link sdk/support.il b/tests/linker-ios/link sdk/support.il new file mode 100644 index 000000000000..67dd10d130fd --- /dev/null +++ b/tests/linker-ios/link sdk/support.il @@ -0,0 +1,11 @@ +// ilasm -dll support.il + +.assembly support { } + +.class public support { + .method static public void throw_object () { + newobj instance void class [mscorlib]System.Object::'.ctor'() + throw + ret + } +}