File size: 7,133 Bytes
05c9ac2
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
121
122
123
124
125
126
127
128
129
130
131
132
133
134
135
136
137
138
139
140
141
142
143
144
145
146
147
148
149
150
151
152
153
154
155
156
157
158
159
160
161
162
163
164
165
166
167
168
169
170
171
172
using System;
using System.IO;
using System.Linq;
using System.Reflection;
using NUnit.Framework;
using UnityEditor;
using UnityEngine;
using Unity.MLAgents;
using Unity.MLAgents.Editor;


namespace MLAgentsExamples.Tests.Settings
{
    [TestFixture]
    public class MLAgentsSettingsTests
    {
        string EditorBuildSettingsConfigKey = MLAgentsSettingsManager.EditorBuildSettingsConfigKey;
        string tempSettingsRootPath = "Assets/ML-Agents/Scripts/Tests/Editor/MLAgentsSettings";
        MLAgentsSettings storedConfigObject;
        [SetUp]
        public void SetUp()
        {
            if (EditorBuildSettings.TryGetConfigObject(EditorBuildSettingsConfigKey,
                out MLAgentsSettings settingsAsset))
            {
                if (settingsAsset != null)
                {
                    storedConfigObject = settingsAsset;
                    EditorBuildSettings.RemoveConfigObject(EditorBuildSettingsConfigKey);
                }
            }
            MLAgentsSettingsManager.Destroy();
            ClearSettingsAssets();
        }

        [TearDown]
        public void TearDown()
        {
            if (storedConfigObject != null)
            {
                EditorBuildSettings.AddConfigObject(EditorBuildSettingsConfigKey, storedConfigObject, true);
                storedConfigObject = null;
            }
            MLAgentsSettingsManager.Destroy();
            ClearSettingsAssets();
        }

        internal void ClearSettingsAssets()
        {
            var assetsGuids = AssetDatabase.FindAssets("t:MLAgentsSettings", new string[] { tempSettingsRootPath });
            foreach (var guid in assetsGuids)
            {
                var path = AssetDatabase.GUIDToAssetPath(guid);
                AssetDatabase.DeleteAsset(path);
            }
        }

        [Test]
        public void TestMLAgentsSettingsManager()
        {
            Assert.AreNotEqual(null, MLAgentsSettingsManager.Settings);
            Assert.AreEqual(5004, MLAgentsSettingsManager.Settings.EditorPort); // default port
            MLAgentsSettingsManager.Settings.EditorPort = 6000;
            Assert.AreEqual(6000, MLAgentsSettingsManager.Settings.EditorPort);

            var settingsObject = ScriptableObject.CreateInstance<MLAgentsSettings>();
            settingsObject.EditorPort = 7000;
            var tempSettingsAssetPath = tempSettingsRootPath + "/test.mlagents.settings.asset";
            AssetDatabase.CreateAsset(settingsObject, tempSettingsAssetPath);
            EditorBuildSettings.AddConfigObject(EditorBuildSettingsConfigKey, settingsObject, true);
            // destroy manager instantiated as a side effect by accessing MLAgentsSettings directly without manager
            MLAgentsSettingsManager.Destroy();
            Assert.AreEqual(7000, MLAgentsSettingsManager.Settings.EditorPort);
        }

        // A mock class that can invoke private methods/fields in MLAgentsSettingsProvider
        internal class MockSettingsProvider
        {
            public MLAgentsSettingsProvider Instance
            {
                get
                {
                    return (MLAgentsSettingsProvider)typeof(MLAgentsSettingsProvider).GetField("s_Instance",
                        BindingFlags.Static | BindingFlags.NonPublic).GetValue(null);
                }
            }

            public MLAgentsSettings Settings
            {
                get
                {
                    return (MLAgentsSettings)typeof(MLAgentsSettingsProvider).GetField("m_Settings",
                        BindingFlags.Instance | BindingFlags.NonPublic).GetValue(Instance);
                }
            }

            public void CreateMLAgentsSettingsProvider()
            {
                MLAgentsSettingsProvider.CreateMLAgentsSettingsProvider();
            }

            public void Reinitialize()
            {
                var method = typeof(MLAgentsSettingsProvider).GetMethod("Reinitialize",
                    BindingFlags.Instance | BindingFlags.NonPublic);
                method.Invoke(Instance, null);
            }

            public string[] FindSettingsInProject()
            {
                var method = typeof(MLAgentsSettingsProvider).GetMethod("FindSettingsInProject",
                    BindingFlags.Static | BindingFlags.NonPublic);
                return (string[])method.Invoke(null, null);
            }

            public void CreateNewSettingsAsset(string relativePath)
            {
                var method = typeof(MLAgentsSettingsProvider).GetMethod("CreateNewSettingsAsset",
                    BindingFlags.Static | BindingFlags.NonPublic);
                method.Invoke(null, new object[] { relativePath });
            }
        }

        [Test]
        public void TestMLAgentsSettingsProviderCreateAsset()
        {
            var mockProvider = new MockSettingsProvider();
            mockProvider.CreateMLAgentsSettingsProvider();
            Assert.AreNotEqual(null, mockProvider.Instance);

            // mimic MLAgentsSettingsProvider.OnActivate()
            MLAgentsSettingsManager.OnSettingsChange += mockProvider.Reinitialize;

            mockProvider.Instance.InitializeWithCurrentSettings();
            Assert.AreEqual(0, mockProvider.FindSettingsInProject().Length);

            var tempSettingsAssetPath1 = tempSettingsRootPath + "/test.mlagents.settings.asset";
            mockProvider.CreateNewSettingsAsset(tempSettingsAssetPath1);
            Assert.AreEqual(1, mockProvider.FindSettingsInProject().Length);
            Assert.AreEqual(5004, mockProvider.Settings.EditorPort);
            MLAgentsSettingsManager.Settings.EditorPort = 6000; // change to something not default
            // callback should update the field in provider
            Assert.AreEqual(6000, mockProvider.Settings.EditorPort);

            var tempSettingsAssetPath2 = tempSettingsRootPath + "/test2.mlagents.settings.asset";
            mockProvider.CreateNewSettingsAsset(tempSettingsAssetPath2);
            Assert.AreEqual(2, mockProvider.FindSettingsInProject().Length);
            // manager should set to the new (default) one, not the previous modified one
            Assert.AreEqual(5004, MLAgentsSettingsManager.Settings.EditorPort);

            // mimic MLAgentsSettingsProvider.OnDeactivate()
            MLAgentsSettingsManager.OnSettingsChange -= mockProvider.Reinitialize;
            mockProvider.Instance.Dispose();
        }

        [Test]
        public void TestMLAgentsSettingsProviderLoadAsset()
        {
            var mockProvider = new MockSettingsProvider();
            var tempSettingsAssetPath1 = tempSettingsRootPath + "/test.mlagents.settings.asset";
            mockProvider.CreateNewSettingsAsset(tempSettingsAssetPath1);
            MLAgentsSettingsManager.Settings.EditorPort = 8000; // change to something not default

            mockProvider.Instance?.Dispose();
            MLAgentsSettingsManager.Destroy();

            mockProvider.CreateMLAgentsSettingsProvider();
            Assert.AreEqual(8000, MLAgentsSettingsManager.Settings.EditorPort);
        }
    }
}