Fix resource stream for collectible assemblies
[platform/upstream/coreclr.git] / tests / src / Regressions / coreclr / GitHub_22888 / test22888.cs
1 // Licensed to the .NET Foundation under one or more agreements.
2 // The .NET Foundation licenses this file to you under the MIT license.
3 // See the LICENSE file in the project root for more information.
4 using System;
5 using System.IO;
6 using System.Reflection;
7 using System.Runtime.CompilerServices;
8 using System.Runtime.Loader;
9
10 class TestAssemblyLoadContext : AssemblyLoadContext
11 {
12     public TestAssemblyLoadContext() : base(isCollectible: true)
13     {
14     }
15
16     protected override Assembly Load(AssemblyName name)
17     {
18         return null;
19     }
20 }
21 public class Test22888
22 {
23     [MethodImpl(MethodImplOptions.NoInlining)]
24     static Stream LoadGetResourceStreamAndUnload(string assemblyPath, out WeakReference alcWeakRef)
25     {
26         var alc = new TestAssemblyLoadContext();
27         alcWeakRef = new WeakReference(alc);
28
29         Assembly a = alc.LoadFromAssemblyPath(assemblyPath);
30         Stream resourceStream = a.GetManifestResourceStream("test22888.resources");
31         alc.Unload();
32
33         return resourceStream;
34     }
35
36     [MethodImpl(MethodImplOptions.NoInlining)]
37     static bool LoadAndUnload(string assemblyPath, out WeakReference alcWeakRef)
38     {
39         Stream s = LoadGetResourceStreamAndUnload(assemblyPath, out alcWeakRef);
40
41         bool success = (s != null);
42
43         if (success)
44         {
45             for (int i = 0; alcWeakRef.IsAlive && (i < 10); i++)
46             {
47                 GC.Collect();
48                 GC.WaitForPendingFinalizers();
49             }
50
51             // Verify that the ALC is still alive - it should be kept alive by the Stream.
52             success = alcWeakRef.IsAlive;
53             if (!success)
54             {
55                 Console.WriteLine("Failed to keep AssemblyLoadContext alive by the resource stream");
56             }
57             GC.KeepAlive(s);
58         }
59         else
60         {
61             Console.WriteLine("Failed to get resource stream from the test assembly");
62         }
63
64         return success;
65     }
66
67     public static int Main()
68     {
69         string currentAssemblyDirectory = Path.GetDirectoryName(new Uri(Assembly.GetExecutingAssembly().CodeBase).AbsolutePath);
70         string testAssemblyFullPath = Path.Combine(currentAssemblyDirectory, "test22888resources.exe");
71
72         WeakReference alcWeakRef;
73         bool success = LoadAndUnload(testAssemblyFullPath, out alcWeakRef);
74
75         if (success)
76         {
77             for (int i = 0; alcWeakRef.IsAlive && (i < 10); i++)
78             {
79                 GC.Collect();
80                 GC.WaitForPendingFinalizers();
81             }
82
83             // Now the ALC should not be alive anymore as the resource stream is gone
84             success =  !alcWeakRef.IsAlive;
85             if (!success)
86             {
87                 Console.WriteLine("Failed to unload the test assembly");
88             }
89         }
90
91         return success ? 100 : 101;
92     }
93 }