chr
2026-04-05 fe750b791d5b517cc4e9bc8e99a9a75139a0cfba
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
//            Copyright Keysight Technologies 2012-2019
// This Source Code Form is subject to the terms of the Mozilla Public
// License, v. 2.0. If a copy of the MPL was not distributed with this
// file, you can obtain one at http://mozilla.org/MPL/2.0/.
using NUnit.Framework;
using System.IO;
using System.Linq;
using System.Xml.Linq;
 
namespace OpenTap.Package.UnitTests
{
    [TestFixture]
    class PackageDefLoadSaveCompare
    {
        /// <summary>
        /// Load the input as a PackageDef, saves it again and compares the saved output to the original input
        /// </summary>
        /// <param name="input"></param>
        private static void LoadSaveCompare(string input, string expectedOutput)
        {
            PackageDef pkg;
            byte[] inputArray = System.Text.Encoding.ASCII.GetBytes(input);
            using (MemoryStream inputStream = new MemoryStream(inputArray))
            {
                pkg = PackageDef.FromXml(inputStream);
            }
            string output = "";
            using (Stream str = new MemoryStream())
            {
                pkg.SaveTo(str);
                using (StreamReader reader = new StreamReader(str))
                {
                    reader.BaseStream.Seek(0, 0);
                    output = reader.ReadToEnd();
                }
            }
            XDocument inputDoc = XDocument.Parse(expectedOutput);
            XDocument outputDoc = XDocument.Parse(output);
            AssertElementEquals(inputDoc.Root, outputDoc.Root);
            AssertElementEquals(outputDoc.Root, inputDoc.Root);
        }
 
        private static void AssertElementEquals(XElement elm1, XElement elm2)
        {
            Assert.AreEqual(elm1.Attributes().Count(), elm2.Attributes().Count(), $"Number of attributes does not match on element {elm1.Name.LocalName}");
            foreach (XAttribute a1 in elm1.Attributes())
            {
                var a2 = elm2.Attribute(a1.Name);
                if (a2 == null)
                    Assert.Fail($"Attribute {a1.Name.LocalName} on element {elm1.Name.LocalName} does not exist in output.");
                if (a1.Value != a2.Value)
                    Assert.Fail($"Value of attribute {a1.Name.LocalName} on element {elm1.Name.LocalName} does not match. ('{a1.Value}' vs. '{a2.Value}')");
            }
            Assert.AreEqual(elm1.Elements().Count(), elm2.Elements().Count(), $"Number of child nodes does not match on element {elm1.Name.LocalName}");
            foreach (var n1 in elm1.Nodes())
            {
                if (n1 is XElement e1)
                {
                    XElement e2 = elm2.Element(e1.Name);
                    if (e2 == null)
                        Assert.Fail($"Output does not contain element {e1.Name.LocalName}.");
                    AssertElementEquals(e1, e2);
                }
                if (n1 is XText t1)
                {
                    Assert.IsTrue(elm2.Nodes().OfType<XText>().Any(t => t.Value == t1.Value), $"Text value '{t1.Value}' does not exist in output.");
                }
            }
        }
 
        /// <summary>
        /// Tests that OS attribute is kept even when empty (as it's default value is non empty ('Windows'))
        /// </summary>
        [Test]
        public void EmptyOS()
        {
            string input = @"<?xml version='1.0' encoding='utf-8'?>
<Package Name='Test' Version='1.2.3-alpha+test' Architecture='AnyCPU' OS='' xmlns='http://opentap.io/schemas/package'>
    <Files>
        <File Path='OpenTap.dll'>
            <SetAssemblyInfo Attributes='Version'/>
        </File>
    </Files>
</Package>";
            LoadSaveCompare(input,input);
        }
 
        /// <summary>
        /// duplicate of the old PackageDefTests.SaveTo_Simple test
        /// </summary>
        [Test]
        public void Simple()
        {
            int retryCount = 10;
            while(retryCount-- > 0)
            {
                string input = @"<?xml version='1.0' encoding='utf-8'?>
    <Package Name='Test' Version='1.2.3-alpha+test' Architecture='AnyCPU' OS='Windows' xmlns='http://opentap.io/schemas/package'>
        <Description>Everything goes here<Status> tags</Status>.</Description>
        <Dependencies>
            <PackageDependency Package='DepName' Version='4.3.2'/>
        </Dependencies>
        <Files>
            <File Path='OpenTap.dll'>
                <SetAssemblyInfo Attributes='Version'/>
                <IgnoreDependency > System.Reflection.Metadata </IgnoreDependency>
            </File>
        </Files>
        <PackageActionExtensions>
            <ActionStep ExpectedExitCodes='0' ActionName='install' Quiet='false' Arguments='+x tap' ExeFile='chmod' Optional='false'></ActionStep>
        </PackageActionExtensions>
    </Package>";
                LoadSaveCompare(input, input);
            }
        }
 
        /// <summary>
        /// Tests that the FileType attribute is removed if it has its default value 'tappackage'
        /// </summary>
        [Test]
        public void DefaultFileType()
        {
            string input = @"<?xml version='1.0' encoding='utf-8'?>
<Package FileType='tappackage' Name='Test' Version='1.2.3-alpha+test' Architecture='AnyCPU' OS='Windows' xmlns='http://opentap.io/schemas/package'>
</Package>";
            string output = @"<?xml version='1.0' encoding='utf-8'?>
<Package Name='Test' Version='1.2.3-alpha+test' Architecture='AnyCPU' OS='Windows' xmlns='http://opentap.io/schemas/package'>
</Package>";
            LoadSaveCompare(input, output);
        }
 
        /// <summary>
        /// Tests that the FileType attribute is removed if it has its default value 'tappackage'
        /// </summary>
        [Test]
        public void NoNamespace()
        {
            string input = @"<?xml version='1.0' encoding='utf-8'?>
<Package Name='Test' Version='1.2.3-alpha+test' Architecture='AnyCPU' OS='Windows'>
</Package>";
            string output = @"<?xml version='1.0' encoding='utf-8'?>
<Package Name='Test' Version='1.2.3-alpha+test' Architecture='AnyCPU' OS='Windows' xmlns='http://opentap.io/schemas/package'>
</Package>";
            LoadSaveCompare(input, output);
        }
 
        /// <summary>
        /// Tests that the FileType attribute is removed if it has its default value 'tappackage'
        /// </summary>
        [Test]
        public void WrongNamespace()
        {
            string input = @"<?xml version='1.0' encoding='utf-8'?>
<Package Name='Test' Version='1.2.3-alpha+test' Architecture='AnyCPU' OS='Windows' xmlns='wrong'>
</Package>";
            string output = @"<?xml version='1.0' encoding='utf-8'?>
<Package Name='Test' Version='1.2.3-alpha+test' Architecture='AnyCPU' OS='Windows' xmlns='http://opentap.io/schemas/package'>
</Package>";
            LoadSaveCompare(input, output);
        }
    }
}