blob: fc6b965ee6f77708cbc1de152c52dd65c08fb534 [file] [log] [blame]
//
// Copyright (c) 2010-2024 Antmicro
//
// This file is licensed under the MIT License.
// Full license text is available in 'licenses/MIT.txt'.
//
using System;
using System.Linq;
using Antmicro.Renode.Core;
using Antmicro.Renode.Peripherals.CPU;
using Antmicro.Renode.PlatformDescription;
using Antmicro.Renode.PlatformDescription.Syntax;
using Antmicro.Renode.Utilities;
using Moq;
using NUnit.Framework;
using Antmicro.Renode.UnitTests.Mocks;
using static Antmicro.Renode.Tests.UnitTests.Mocks.MockPeripheralWithEnumAttribute;
using System.Security.Policy;
namespace Antmicro.Renode.UnitTests.PlatformDescription
{
[TestFixture]
public class MergeAndCreationTests
{
[Test]
public void ShouldUpdateRegistrationPoint()
{
var source = @"
register1: Antmicro.Renode.UnitTests.Mocks.NullRegister @ sysbus <0, 100>
register2: Antmicro.Renode.UnitTests.Mocks.NullRegister @ sysbus new Antmicro.Renode.Peripherals.Bus.BusRangeRegistration { range: <100, +100> }
cpu: Antmicro.Renode.UnitTests.Mocks.MockCPU @ register1
cpu: @register2";
ProcessSource(source);
ICPU peripheral;
Assert.IsTrue(machine.TryGetByName("sysbus.register2.cpu", out peripheral));
Assert.IsFalse(machine.TryGetByName("sysbus.register1.cpu", out peripheral));
}
[Test]
public void ShouldCancelRegistration()
{
var source = @"
register: Antmicro.Renode.UnitTests.Mocks.NullRegister @ sysbus <0, 100>
cpu: Antmicro.Renode.UnitTests.Mocks.MockCPU @ register
cpu: @none";
ProcessSource(source);
ICPU peripheral;
Assert.IsFalse(machine.TryGetByName("sysbus.register.cpu", out peripheral));
}
[Test]
public void ShouldHandleRegistrationInReverseOrder()
{
var source = @"
cpu: Antmicro.Renode.UnitTests.Mocks.MockCPU @ register
register: Antmicro.Renode.UnitTests.Mocks.NullRegister @ sysbus <0, 100>
";
ProcessSource(source);
ICPU peripheral;
Assert.IsTrue(machine.TryGetByName("sysbus.register.cpu", out peripheral));
}
[Test]
public void ShouldHandleAlias()
{
var source = @"
cpu: Antmicro.Renode.UnitTests.Mocks.MockCPU @ sysbus as ""otherName""";
ProcessSource(source);
ICPU peripheral;
Assert.IsTrue(machine.TryGetByName("sysbus.otherName", out peripheral));
Assert.IsFalse(machine.TryGetByName("sysbus.cpu", out peripheral));
}
[Test]
public void ShouldUpdateProperty()
{
var source = @"
cpu: Antmicro.Renode.UnitTests.Mocks.MockCPU @ sysbus
Placeholder: ""one""
EnumValue: TwoStateEnum.Two
cpu:
Placeholder: ""two""";
ProcessSource(source);
MockCPU mock;
Assert.IsTrue(machine.TryGetByName("sysbus.cpu", out mock));
Assert.AreEqual("two", mock.Placeholder);
Assert.AreEqual(TwoStateEnum.Two, mock.EnumValue);
}
[Test]
public void ShouldHandleEscapedOuoteInString()
{
var source = @"
cpu: Antmicro.Renode.UnitTests.Mocks.MockCPU @ sysbus
Placeholder: ""one with \""escaped\"" quote\""""";
ProcessSource(source);
MockCPU mock;
Assert.IsTrue(machine.TryGetByName("sysbus.cpu", out mock));
Assert.AreEqual("one with \"escaped\" quote\"", mock.Placeholder);
}
[Test]
public void ShouldHandleMultilineQuotedStringAsValue()
{
var source = @"
cpu: Antmicro.Renode.UnitTests.Mocks.MockCPU @ sysbus
Placeholder: '''this is
multiline
string'''";
ProcessSource(source);
MockCPU mock;
Assert.IsTrue(machine.TryGetByName("sysbus.cpu", out mock));
Assert.AreEqual("this is\nmultiline\nstring", mock.Placeholder);
}
[Test]
public void ShouldHandleMultipleMultilineQuotedStrings()
{
var source = @"
cpu: Antmicro.Renode.UnitTests.Mocks.MockCPU @ sysbus
Placeholder: '''this is a
multiline
string'''
cpu2: Antmicro.Renode.UnitTests.Mocks.MockCPU @ sysbus
Placeholder: '''this is another
multilineeee
stringgggg'''";
ProcessSource(source);
MockCPU mock1;
MockCPU mock2;
Assert.IsTrue(machine.TryGetByName("sysbus.cpu", out mock1));
Assert.IsTrue(machine.TryGetByName("sysbus.cpu2", out mock2));
Assert.AreEqual("this is a\nmultiline\nstring", mock1.Placeholder);
Assert.AreEqual("this is another\nmultilineeee\nstringgggg", mock2.Placeholder);
}
[Test]
public void ShouldFailOnUnclosedMultipleMultilineQuotedStrings()
{
var source = @"
cpu: Antmicro.Renode.UnitTests.Mocks.MockCPU @ sysbus
Placeholder: '''this is
multiline
string'''
cpu2: Antmicro.Renode.UnitTests.Mocks.MockCPU @ sysbus
Placeholder: '''this is
multiline
string'''
cpu3: Antmicro.Renode.UnitTests.Mocks.MockCPU @ sysbus
Placeholder: '''this is
multiline
string";
var exception = Assert.Throws<ParsingException>(() => ProcessSource(source));
Assert.AreEqual(ParsingError.SyntaxError, exception.Error);
var position = exception.Message.Split(new string[] { Environment.NewLine }, StringSplitOptions.None)[1];
Assert.AreEqual("At 11:17:", position);
}
[Test]
public void ShouldFailOnUnclosedMultilineQuotedStringBetweenQuotedStrings()
{
var source = @"
cpu: Antmicro.Renode.UnitTests.Mocks.MockCPU @ sysbus
Placeholder: '''this is
multiline
string'''
cpu2: Antmicro.Renode.UnitTests.Mocks.MockCPU @ sysbus
Placeholder: '''this is
multiline
string
cpu3: Antmicro.Renode.UnitTests.Mocks.MockCPU @ sysbus
Placeholder: '''this is
multiline'''
string";
var exception = Assert.Throws<ParsingException>(() => ProcessSource(source));
Assert.AreEqual(ParsingError.SyntaxError, exception.Error);
var position = exception.Message.Split(new string[] { Environment.NewLine }, StringSplitOptions.None)[1];
Assert.AreEqual("At 12:9:", position);
}
[Test, Ignore("Ignored")]
public void ShouldHandleEscapedMultilineStringQuoteInSingleLineQuotedString()
{
var source = @"
cpu: Antmicro.Renode.UnitTests.Mocks.MockCPU @ sysbus
Placeholder: ""one with \''' escaped quote""";
ProcessSource(source);
MockCPU mock;
Assert.IsTrue(machine.TryGetByName("sysbus.cpu", out mock));
Assert.AreEqual("one with ''' escaped quote", mock.Placeholder);
}
[Test, Ignore("Ignored")]
public void ShouldHandleMultipleEscapeCharsInMultilineString()
{
var source = @"
cpu: Antmicro.Renode.UnitTests.Mocks.MockCPU @ sysbus
Placeholder: '''one with escaped quote\\'''";
ProcessSource(source);
MockCPU mock;
Assert.IsTrue(machine.TryGetByName("sysbus.cpu", out mock));
Assert.AreEqual("one with escaped quote\\", mock.Placeholder);
}
[Test]
public void ShouldHandleMultilineQuotedStringInOneLine()
{
var source = @"
cpu: Antmicro.Renode.UnitTests.Mocks.MockCPU @ sysbus
Placeholder: '''this is single line'''";
ProcessSource(source);
MockCPU mock;
Assert.IsTrue(machine.TryGetByName("sysbus.cpu", out mock));
Assert.AreEqual("this is single line", mock.Placeholder);
}
[Test]
public void ShouldFailOnMultilineQuotedStringInUsing()
{
var source = @"
using '''this is
multiline
string '''";
var exception = Assert.Throws<ParsingException>(() => ProcessSource(source));
Assert.AreEqual(ParsingError.SyntaxError, exception.Error);
}
[Test]
public void ShouldHandleEscapedQuoteInMultilineString()
{
var source = @"
cpu: Antmicro.Renode.UnitTests.Mocks.MockCPU @ sysbus
Placeholder: '''this is \''' single line'''";
ProcessSource(source);
MockCPU mock;
Assert.IsTrue(machine.TryGetByName("sysbus.cpu", out mock));
Assert.AreEqual("this is ''' single line", mock.Placeholder);
}
[Test]
public void ShouldHandleEscapedUnescapedSingleQuoteCharInMultilineString()
{
var source = @"
cpu: Antmicro.Renode.UnitTests.Mocks.MockCPU @ sysbus
Placeholder: ''' this is string with ' and '' '''";
ProcessSource(source);
MockCPU mock;
Assert.IsTrue(machine.TryGetByName("sysbus.cpu", out mock));
Assert.AreEqual(" this is string with ' and '' ", mock.Placeholder);
}
[Test]
public void ShouldFailOnAnyStringAfterClosedMultilineString()
{
var source = @"
cpu: Antmicro.Renode.UnitTests.Mocks.MockCPU @ sysbus
Placeholder: '''this is
not a single line ''' xx";
var exception = Assert.Throws<ParsingException>(() => ProcessSource(source));
Assert.AreEqual(ParsingError.SyntaxError, exception.Error);
var position = exception.Message.Split(new string[] { Environment.NewLine }, StringSplitOptions.None)[1];
Assert.AreEqual("At 4:23:", position);
}
[Test]
public void ShouldFailOnMultipleMultilineStringSignsInOneLine()
{
var source = @"
cpu: Antmicro.Renode.UnitTests.Mocks.MockCPU @ sysbus
Placeholder: '''this is \''' ''' ''' '''
not a single line '''";
var exception = Assert.Throws<ParsingException>(() => ProcessSource(source));
Assert.AreEqual(ParsingError.SyntaxError, exception.Error);
var position = exception.Message.Split(new string[] { Environment.NewLine }, StringSplitOptions.None)[1];
Assert.AreEqual("At 4:18:", position);
}
[Test]
public void ShouldHandleMultipleEscapedMultilineStringSignsInOneLine()
{
var source = @"
cpu: Antmicro.Renode.UnitTests.Mocks.MockCPU @ sysbus
Placeholder: '''this is \''' \''' \''' \'''
not a single line '''";
ProcessSource(source);
MockCPU mock;
Assert.IsTrue(machine.TryGetByName("sysbus.cpu", out mock));
Assert.AreEqual("this is ''' ''' ''' '''\nnot a single line ", mock.Placeholder);
}
[Test]
public void ShouldFailOnUnclosedMultilineString()
{
var source = @"
cpu: Antmicro.Renode.UnitTests.Mocks.MockCPU @ sysbus
Placeholder: '''this is ";
var exception = Assert.Throws<ParsingException>(() => ProcessSource(source));
Assert.AreEqual(ParsingError.SyntaxError, exception.Error);
var position = exception.Message.Split(new string[] { Environment.NewLine }, StringSplitOptions.None)[1];
Assert.AreEqual("At 3:17:", position);
}
[Test]
public void ShouldHandleEscapedMultilineStringSignInNewLine()
{
var source = @"
cpu: Antmicro.Renode.UnitTests.Mocks.MockCPU @ sysbus
Placeholder: '''this is
\'''
not a single line '''";
ProcessSource(source);
MockCPU mock;
Assert.IsTrue(machine.TryGetByName("sysbus.cpu", out mock));
Assert.AreEqual("this is \n\'''\nnot a single line ", mock.Placeholder);
}
[Test]
public void ShouldHandleEscapedMultilineStringSignAtTheEndOfALine()
{
var source = @"
cpu: Antmicro.Renode.UnitTests.Mocks.MockCPU @ sysbus
Placeholder: '''this is \'''
not a single line '''";
ProcessSource(source);
MockCPU mock;
Assert.IsTrue(machine.TryGetByName("sysbus.cpu", out mock));
Assert.AreEqual("this is \'''\nnot a single line ", mock.Placeholder);
}
[Test, Ignore("Ignored")]
public void ShouldHandleMultipleBackslashesAsEscapingCharacters()
{
var source = @"
cpu: Antmicro.Renode.UnitTests.Mocks.MockCPU @ sysbus
Placeholder: '''this is \\\'''
not a single line '''";
ProcessSource(source);
MockCPU mock;
Assert.IsTrue(machine.TryGetByName("sysbus.cpu", out mock));
Assert.AreEqual(@"this is \\\'''
not a single line ", mock.Placeholder);
}
[Test]
public void ShouldHandleNoneInProperty()
{
var source = @"
cpu: Antmicro.Renode.UnitTests.Mocks.MockCPU @ sysbus
EnumValue: TwoStateEnum.Two
cpu:
EnumValue: none";
ProcessSource(source);
MockCPU mock;
Assert.IsTrue(machine.TryGetByName("sysbus.cpu", out mock));
Assert.AreEqual(TwoStateEnum.One, mock.EnumValue);
}
[Test]
public void ShouldHandleEmptyNumericalValue()
{
var source = @"
mockPeripheral: Antmicro.Renode.Tests.UnitTests.Mocks.MockPeripheralWithNumericalAttrubute @ sysbus <0, 1>
mockInt: empty";
ProcessSource(source);
Tests.UnitTests.Mocks.MockPeripheralWithNumericalAttrubute mockPeripheral;
Assert.IsTrue(machine.TryGetByName("sysbus.mockPeripheral", out mockPeripheral));
Assert.AreEqual(default(int), mockPeripheral.MockInt);
}
[Test]
public void ShouldHandleEmptyStringValue()
{
var source = @"
mockPeripheral: Antmicro.Renode.Tests.UnitTests.Mocks.MockPeripheralWithStringAttribute @ sysbus <0, 1>
mockString: empty";
ProcessSource(source);
Tests.UnitTests.Mocks.MockPeripheralWithStringAttribute mockPeripheral;
Assert.IsTrue(machine.TryGetByName("sysbus.mockPeripheral", out mockPeripheral));
Assert.AreEqual(default(string), mockPeripheral.MockString);
}
[Test]
public void ShouldHandleEmptyEnumValue()
{
var source = @"
cpu: Antmicro.Renode.UnitTests.Mocks.MockCPU @ sysbus
EnumValue: empty";
ProcessSource(source);
MockCPU mock;
Assert.IsTrue(machine.TryGetByName("sysbus.cpu", out mock));
Assert.AreEqual(default(TwoStateEnum), mock.EnumValue);
}
[Test]
public void ShouldHandleEmptyRangeValue()
{
var source = @"
mockPeripheral: Antmicro.Renode.Tests.UnitTests.Mocks.MockPeripheralWithRangeAttribute @ sysbus <0, 1>
mockRange: empty";
ProcessSource(source);
Tests.UnitTests.Mocks.MockPeripheralWithRangeAttribute mockPeripheral;
Assert.IsTrue(machine.TryGetByName("sysbus.mockPeripheral", out mockPeripheral));
Assert.AreEqual(default(Core.Range), mockPeripheral.MockRange);
}
[Test]
public void ShouldHandleEmptyObjectValue()
{
var source = @"
mockPeripheral: Antmicro.Renode.Tests.UnitTests.Mocks.MockPeripheralWithObjectAttribute @ sysbus <0, 1>
mockObject: empty";
ProcessSource(source);
Tests.UnitTests.Mocks.MockPeripheralWithObjectAttribute mockPeripheral;
Assert.IsTrue(machine.TryGetByName("sysbus.mockPeripheral", out mockPeripheral));
Assert.AreEqual(default(Object), mockPeripheral.MockObject);
}
[Test]
public void ShouldHandleEmptyBoolValue()
{
var source = @"
mockPeripheral: Antmicro.Renode.Tests.UnitTests.Mocks.MockPeripheralWithBoolAttribute @ sysbus <0, 1>
mockBool: empty";
ProcessSource(source);
Tests.UnitTests.Mocks.MockPeripheralWithBoolAttribute mockPeripheral;
Assert.IsTrue(machine.TryGetByName("sysbus.mockPeripheral", out mockPeripheral));
Assert.AreEqual(default(bool), mockPeripheral.MockBool);
}
[Test]
public void ShouldHandleEmptyReferenceAttribute()
{
var source = @"
mockPeripheral: Antmicro.Renode.Tests.UnitTests.Mocks.MockPeripheralUsingReferenceAttribute @ sysbus <0, 1>
mockReference: empty";
ProcessSource(source);
Tests.UnitTests.Mocks.MockPeripheralUsingReferenceAttribute mockPeripheral;
Assert.IsTrue(machine.TryGetByName("sysbus.mockPeripheral", out mockPeripheral));
Assert.AreEqual(default(Antmicro.Renode.Peripherals.IPeripheral), mockPeripheral.MockReference);
}
[Test]
public void ShouldFailOnEmptyKeywordAsType()
{
var source = @"
mockPeripheral: empty @ sysbus <0, 1>
value: 0";
var exception = Assert.Throws<ParsingException>(() => ProcessSource(source));
Assert.AreEqual(ParsingError.SyntaxError, exception.Error);
}
[Test]
public void ShouldFailOnEmptyKeywordAsRegistrationDestination()
{
var source = @"
mockPeripheral: Antmicro.Renode.UnitTests.Mocks.EmptyPeripheral @ empty <0, 1>
value: 0";
var exception = Assert.Throws<ParsingException>(() => ProcessSource(source));
Assert.AreEqual(ParsingError.SyntaxError, exception.Error);
}
[Test]
public void ShouldFailOnEmptyKeywordAsParameterName()
{
var source = @"
mockPeripheral: Antmicro.Renode.UnitTests.Mocks.EmptyPeripheral @ sysbus <0, 1>
empty: 0";
var exception = Assert.Throws<ParsingException>(() => ProcessSource(source));
Assert.AreEqual(ParsingError.SyntaxError, exception.Error);
}
[Test]
public void ShouldFailOnEmptyKeywordAsUsingParameter()
{
var source = @"using empty";
var exception = Assert.Throws<ParsingException>(() => ProcessSource(source));
Assert.AreEqual(ParsingError.SyntaxError, exception.Error);
}
[Test]
public void ShouldHandleNoneInCtorParam()
{
var source = @"
peripheral: Antmicro.Renode.UnitTests.Mocks.EmptyPeripheral @ sysbus <0, 1>
value: 1
peripheral:
value: none";
ProcessSource(source);
EmptyPeripheral peripheral;
Assert.IsTrue(machine.TryGetByName("sysbus.peripheral", out peripheral));
Assert.AreEqual(1, peripheral.Counter);
}
[Test]
public void ShouldUpdateSingleInterrupt()
{
var source = @"
sender: Antmicro.Renode.UnitTests.Mocks.MockIrqSender @ sysbus <0, 1>
[Irq] -> receiver@[0]
receiver: Antmicro.Renode.UnitTests.Mocks.MockReceiver @ sysbus <1, 2>
sender:
Irq -> receiver@1";
ProcessSource(source);
MockIrqSender sender;
Assert.IsTrue(machine.TryGetByName("sysbus.sender", out sender));
Assert.AreEqual(1, sender.Irq.Endpoints[0].Number);
}
[Test]
public void ShouldHandleManyMultiplexedMultiDestinationInterrupts()
{
var source = @"
sender: Antmicro.Renode.UnitTests.Mocks.MockGPIOByNumberConnectorPeripheral @ sysbus <3, 4>
gpios: 2
[0, Irq] -> receiver@[1-2] | receiver2@[3-4] | receiver3@[5-6]
receiver: Antmicro.Renode.UnitTests.Mocks.MockReceiver @ sysbus <0, 1>
receiver2: Antmicro.Renode.UnitTests.Mocks.MockReceiver @ sysbus <1, 2>
receiver3: Antmicro.Renode.UnitTests.Mocks.MockReceiver @ sysbus <2, 3>";
ProcessSource(source);
MockGPIOByNumberConnectorPeripheral sender;
MockReceiver receiver, receiver2, receiver3;
Assert.IsTrue(machine.TryGetByName("sysbus.sender", out sender));
Assert.IsTrue(machine.TryGetByName("sysbus.receiver", out receiver));
Assert.IsTrue(machine.TryGetByName("sysbus.receiver2", out receiver2));
Assert.IsTrue(machine.TryGetByName("sysbus.receiver3", out receiver3));
Assert.AreEqual(3, sender.Irq.Endpoints.Count);
Assert.AreEqual(2, sender.Irq.Endpoints[0].Number);
Assert.AreEqual(4, sender.Irq.Endpoints[1].Number);
Assert.AreEqual(6, sender.Irq.Endpoints[2].Number);
Assert.AreEqual(receiver, sender.Irq.Endpoints[0].Receiver);
Assert.AreEqual(receiver2, sender.Irq.Endpoints[1].Receiver);
Assert.AreEqual(receiver3, sender.Irq.Endpoints[2].Receiver);
}
[Test]
public void ShouldCancelIrqConnection()
{
var source = @"
sender: Antmicro.Renode.UnitTests.Mocks.MockIrqSender @ sysbus <0, 1> { [Irq] -> receiver@[0] }
receiver: Antmicro.Renode.UnitTests.Mocks.MockReceiver @ sysbus <1, 2>
sender:
Irq -> none";
ProcessSource(source);
MockIrqSender sender;
Assert.IsTrue(machine.TryGetByName("sysbus.sender", out sender));
Assert.IsFalse(sender.Irq.IsConnected);
}
[Test]
public void ShouldUpdateDefaultIrq()
{
var source = @"
sender: Antmicro.Renode.UnitTests.Mocks.MockIrqSender @ sysbus <0, 1>
[Irq] -> receiver@[0]
receiver: Antmicro.Renode.UnitTests.Mocks.MockReceiver @ sysbus <1, 2>
sender:
-> receiver@2";
ProcessSource(source);
MockIrqSender sender;
Assert.IsTrue(machine.TryGetByName("sysbus.sender", out sender));
Assert.AreEqual(2, sender.Irq.Endpoints[0].Number);
}
[Test]
public void ShouldUpdateMultiInterrupts()
{
var a = @"
sender: Antmicro.Renode.UnitTests.Mocks.MockGPIOByNumberConnectorPeripheral @ sysbus <0, 1>
gpios: 64
[0-2, 3-5, Irq, OtherIrq] -> receiver@[0-7] | receiver@[8-15]
6 -> receiver2@7
receiver: Antmicro.Renode.UnitTests.Mocks.MockReceiver @ sysbus<1, 2>
receiver2: Antmicro.Renode.UnitTests.Mocks.MockReceiver @ sysbus<2, 3>";
var source = @"
using ""A""
sender:
[Irq, 3-4] -> receiver2@[0-2]
6 -> receiver@16
[7-8] -> receiver@[17-18]
";
ProcessSource(source, a);
MockGPIOByNumberConnectorPeripheral sender;
MockReceiver receiver1, receiver2;
Assert.IsTrue(machine.TryGetByName("sysbus.sender", out sender));
Assert.IsTrue(machine.TryGetByName("sysbus.receiver", out receiver1));
Assert.IsTrue(machine.TryGetByName("sysbus.receiver2", out receiver2));
Assert.AreEqual(0, sender.Irq.Endpoints[0].Number);
Assert.AreEqual(receiver2, sender.Irq.Endpoints[0].Receiver);
Assert.AreEqual(7, sender.OtherIrq.Endpoints[0].Number);
Assert.AreEqual(receiver1, sender.OtherIrq.Endpoints[0].Receiver);
Assert.AreEqual(0, sender.Connections[0].Endpoints[0].Number);
Assert.AreEqual(receiver1, sender.Connections[0].Endpoints[0].Receiver);
Assert.AreEqual(1, sender.Connections[1].Endpoints[0].Number);
Assert.AreEqual(receiver1, sender.Connections[1].Endpoints[0].Receiver);
Assert.AreEqual(2, sender.Connections[2].Endpoints[0].Number);
Assert.AreEqual(receiver1, sender.Connections[2].Endpoints[0].Receiver);
Assert.AreEqual(1, sender.Connections[3].Endpoints[0].Number);
Assert.AreEqual(receiver2, sender.Connections[3].Endpoints[0].Receiver);
Assert.AreEqual(2, sender.Connections[4].Endpoints[0].Number);
Assert.AreEqual(receiver2, sender.Connections[4].Endpoints[0].Receiver);
Assert.AreEqual(5, sender.Connections[5].Endpoints[0].Number);
Assert.AreEqual(receiver1, sender.Connections[5].Endpoints[0].Receiver);
Assert.AreEqual(16, sender.Connections[6].Endpoints[0].Number);
Assert.AreEqual(receiver1, sender.Connections[6].Endpoints[0].Receiver);
Assert.AreEqual(17, sender.Connections[7].Endpoints[0].Number);
Assert.AreEqual(receiver1, sender.Connections[7].Endpoints[0].Receiver);
Assert.AreEqual(18, sender.Connections[8].Endpoints[0].Number);
Assert.AreEqual(receiver1, sender.Connections[8].Endpoints[0].Receiver);
}
[Test]
public void ShouldFailOnUsingAlreadyRegisteredPeripheralsName()
{
var source = @"
peripheral: Antmicro.Renode.UnitTests.Mocks.MockCPU";
var peripheral = new EmptyPeripheral();
machine.SystemBus.Register(peripheral, new Antmicro.Renode.Peripherals.Bus.BusRangeRegistration(0.To(1)));
machine.SetLocalName(peripheral, "peripheral");
var exception = Assert.Throws<ParsingException>(() => ProcessSource(source));
Assert.AreEqual(ParsingError.VariableAlreadyDeclared, exception.Error);
}
[Test]
public void ShouldTakeAlreadyRegisteredPeripheralsAsVariables()
{
var source = @"
newCpu: Antmicro.Renode.UnitTests.Mocks.MockCPU @ sysbus 2
OtherCpu: cpu";
var cpu = new MockCPU(machine);
machine.SystemBus.Register(cpu, new CPURegistrationPoint(1));
machine.SetLocalName(cpu, "cpu");
ProcessSource(source);
MockCPU otherMockCpu;
Assert.IsTrue(machine.TryGetByName("sysbus.newCpu", out otherMockCpu));
Assert.AreEqual(cpu, otherMockCpu.OtherCpu);
}
[Test]
public void ShouldNotDetectCycleInPerCoreRegistration()
{
var source = @"
core1_nvic: IRQControllers.NVIC @ sysbus new Bus.BusPointRegistration {
address: 0xE000E000;
cpu: cpu1
}
core2_nvic: IRQControllers.NVIC @ sysbus new Bus.BusPointRegistration {
address: 0xE000E000;
cpu: cpu2
}
cpu1: CPU.CortexM @ sysbus
cpuType: ""cortex-m0""
nvic: core1_nvic
cpu2: CPU.CortexM @ sysbus
cpuType: ""cortex-m0""
nvic: core2_nvic";
ProcessSource(source);
}
[Test]
public void ShouldNotDetectCycleInSignalConnection()
{
var source = @"
clint: IRQControllers.CoreLevelInterruptor @ {
sysbus new Bus.BusPointRegistration { address: 0x002000000; cpu: cpu_rv }
}
[0,1] -> cpu_rv@[3,7]
frequency: 10000000
cpu_rv: CPU.RiscV32 @ sysbus
cpuType: ""rv32ima""
timeProvider: clint";
ProcessSource(source);
}
[Test]
public void ShouldReplaceInit()
{
var source = @"
peri: Antmicro.Renode.UnitTests.Mocks.EmptyPeripheral @ sysbus <0, 1>
init:
Increment
peri:
init:
Increment
Increment";
ProcessSource(source);
initHandlerMock.Verify(x => x.Execute(It.IsAny<IInitable>(), new[] { "Increment", "Increment" }, It.IsAny<Action<string>>()));
}
[Test]
public void ShouldAddInit()
{
var source = @"
peri: Antmicro.Renode.UnitTests.Mocks.EmptyPeripheral
init:
Increment
peri:
init add:
Increment
Increment";
ProcessSource(source);
initHandlerMock.Verify(x => x.Execute(It.IsAny<IInitable>(), new[] { "Increment", "Increment", "Increment" }, It.IsAny<Action<string>>()));
}
[Test]
public void ShouldUpdateSysbusInit()
{
var source = @"
sysbus:
init:
WriteByte 0 1";
ProcessSource(source);
initHandlerMock.Verify(x => x.Execute(It.IsAny<IInitable>(), new[] { "WriteByte 0 1" }, It.IsAny<Action<string>>()));
}
[Test]
public void ShouldFailOnNotValidatedInit()
{
var a = @"
peri: Antmicro.Renode.UnitTests.Mocks.EmptyPeripheral
init:
Increment
Increment";
var source = @"
using ""A""
peri:
init:
Increment";
var errorMessage = "Invalid init section";
initHandlerMock.Setup(x => x.Validate(It.IsAny<IInitable>(), out errorMessage)).Returns(false);
var exception = Assert.Throws<ParsingException>(() => ProcessSource(source, a));
Assert.AreEqual(ParsingError.InitSectionValidationError, exception.Error);
}
[Test]
public void ShouldFindCyclicDependency()
{
var source = @"
peri1: Antmicro.Renode.UnitTests.Mocks.MockPeripheralWithDependency
other: new Antmicro.Renode.UnitTests.Mocks.MockPeripheralWithDependency
other: peri2
peri3: Antmicro.Renode.UnitTests.Mocks.MockPeripheralWithDependency
other: peri4
peri4: Antmicro.Renode.UnitTests.Mocks.MockPeripheralWithDependency
other: peri1
peri2: Antmicro.Renode.UnitTests.Mocks.MockPeripheralWithDependency
other: peri3
";
var exception = Assert.Throws<ParsingException>(() => ProcessSource(source));
Assert.AreEqual(ParsingError.CreationOrderCycle, exception.Error);
}
[Test]
public void ShouldFindCyclicReferenceToItself()
{
var source = @"
peri: Antmicro.Renode.UnitTests.Mocks.MockPeripheralWithDependency
other: peri";
var exception = Assert.Throws<ParsingException>(() => ProcessSource(source));
Assert.AreEqual(ParsingError.CreationOrderCycle, exception.Error);
}
[Test]
public void ShouldFindCyclicReferenceBetweenFiles()
{
var a = @"
peri1: Antmicro.Renode.UnitTests.Mocks.MockPeripheralWithDependency
other: peri3
peri3: Antmicro.Renode.UnitTests.Mocks.MockPeripheralWithDependency
";
var source = @"
using ""A""
peri2: Antmicro.Renode.UnitTests.Mocks.MockPeripheralWithDependency
other: peri1
peri3:
other: peri2";
var exception = Assert.Throws<ParsingException>(() => ProcessSource(source, a));
Assert.AreEqual(ParsingError.CreationOrderCycle, exception.Error);
}
[Test]
public void ShouldSetPropertyOfInlineObject()
{
var source = @"
cpu: Antmicro.Renode.UnitTests.Mocks.MockCPU @ sysbus
OtherCpu: new Antmicro.Renode.UnitTests.Mocks.MockCPU
OtherCpu: new Antmicro.Renode.UnitTests.Mocks.MockCPU
Placeholder: ""something""";
ProcessSource(source);
MockCPU cpu;
Assert.IsTrue(machine.TryGetByName("sysbus.cpu", out cpu));
Assert.AreEqual("something", ((cpu.OtherCpu as MockCPU).OtherCpu as MockCPU).Placeholder);
}
[Test]
public void ShouldRegisterPeripheralWithManyRegistrationPoints()
{
var source = @"
peripheral: Antmicro.Renode.UnitTests.Mocks.EmptyPeripheral @{
sysbus <0x100, +0x10>;
sysbus <0x200, +0x20>} as ""alias""
";
ProcessSource(source);
EmptyPeripheral peripheral;
Assert.IsTrue(machine.TryGetByName("sysbus.alias", out peripheral));
var ranges = machine.GetPeripheralRegistrationPoints(machine.SystemBus, peripheral).OfType<Antmicro.Renode.Peripherals.Bus.BusRangeRegistration>().Select(x => x.Range).ToArray();
Assert.AreEqual(0x100.By(0x10), ranges[0]);
Assert.AreEqual(0x200.By(0x20), ranges[1]);
Assert.AreEqual(2, ranges.Length);
}
[Test]
public void ShouldFailOnNonExistingReferenceInCtorAttribute()
{
var source = @"
peripheral: Antmicro.Renode.UnitTests.Mocks.MockPeripheralWithDependency
other: nonExististing";
var exception = Assert.Throws<ParsingException>(() => ProcessSource(source));
Assert.AreEqual(ParsingError.MissingReference, exception.Error);
}
[Test]
public void ShouldProcessEntryDependantOnSysbus()
{
var source = @"
peripheral: Antmicro.Renode.UnitTests.Mocks.MockPeripheralWithDependency
other: sysbus";
ProcessSource(source);
}
[Test]
public void ShouldProcessEntryDependantOnSysbusWithUpdateEntry()
{
var source = @"
sysbus:
init:
Method
peripheral: Antmicro.Renode.UnitTests.Mocks.MockPeripheralWithDependency
other: sysbus";
ProcessSource(source);
}
[Test]
public void ShouldCatchExceptionOnEntryConstruction()
{
var source = @"
peripheral: Antmicro.Renode.UnitTests.Mocks.MockPeripheralWithDependency
throwException: true";
var exception = Assert.Throws<ParsingException>(() => ProcessSource(source));
Assert.AreEqual(ParsingError.ConstructionException, exception.Error);
}
[Test]
public void ShouldCatchExceptionOnObjectValueConstruction()
{
var source = @"
peripheral: Antmicro.Renode.UnitTests.Mocks.MockPeripheralWithDependency
other: new Antmicro.Renode.UnitTests.Mocks.MockPeripheralWithDependency
throwException: true";
var exception = Assert.Throws<ParsingException>(() => ProcessSource(source));
Assert.AreEqual(ParsingError.ConstructionException, exception.Error);
}
[Test]
public void ShouldCatchExceptionOnPropertySetting()
{
var source = @"
peripheral: Antmicro.Renode.UnitTests.Mocks.EmptyPeripheral
ThrowingProperty: 1";
var exception = Assert.Throws<ParsingException>(() => ProcessSource(source));
Assert.AreEqual(ParsingError.PropertySettingException, exception.Error);
}
[Test]
public void ShouldCatchExceptionOnRegistration()
{
var source = @"
peripheral: Antmicro.Renode.UnitTests.Mocks.EmptyPeripheral @ {
sysbus <0x100, +0x100>;
sysbus <0x150, +0x100>
}";
var exception = Assert.Throws<ParsingException>(() => ProcessSource(source));
Assert.AreEqual(ParsingError.RegistrationException, exception.Error);
}
[Test]
public void ShouldHandleNameConflict()
{
var source = @"
p1: Antmicro.Renode.UnitTests.Mocks.EmptyPeripheral @ sysbus <0x100, +0x50>
p2: Antmicro.Renode.UnitTests.Mocks.EmptyPeripheral @ sysbus <0x200, +0x50> as ""p1""
";
var exception = Assert.Throws<ParsingException>(() => ProcessSource(source));
Assert.AreEqual(ParsingError.NameSettingException, exception.Error);
}
[Test]
public void ShouldProcessRepeatedRegistration()
{
var source = @"
mockRegister1: Antmicro.Renode.UnitTests.Mocks.MockRegister @ sysbus 0x0
cpu: Antmicro.Renode.UnitTests.Mocks.MockCPU @ {
mockRegister1;
mockRegister2
}
mockRegister2: Antmicro.Renode.UnitTests.Mocks.MockRegister @ sysbus 0x100
";
ProcessSource(source);
ICPU peripheral;
Assert.IsTrue(machine.TryGetByName("sysbus.mockRegister1.cpu", out peripheral));
Assert.IsTrue(machine.TryGetByName("sysbus.mockRegister2.cpu", out peripheral));
}
[Test]
public void ShouldProcessValidEnum()
{
var source = @"
mockPeripheral: Antmicro.Renode.Tests.UnitTests.Mocks.MockPeripheralWithEnumAttribute @ sysbus <0, 1>
mockEnum: MockEnum.ValidValue
";
ProcessSource(source);
var result = machine.TryGetByName("sysbus.mockPeripheral", out Tests.UnitTests.Mocks.MockPeripheralWithEnumAttribute mockPeripheral);
Assert.IsTrue(result);
Assert.AreEqual(MockEnum.ValidValue, mockPeripheral.MockEnumValue);
}
[Test]
public void ShouldFailOnInvalidEnum()
{
var source = @"
peripheral: Antmicro.Renode.Tests.UnitTests.Mocks.MockPeripheralWithEnumAttribute
mockEnum: MockEnum.InvalidValue
";
var exception = Assert.Throws<ParsingException>(() => ProcessSource(source));
Assert.AreEqual(ParsingError.NoCtor, exception.Error);
}
[Test]
public void ShouldProcessValidIntAsEnum()
{
var source = @"
peripheral: Antmicro.Renode.Tests.UnitTests.Mocks.MockPeripheralWithEnumAttribute @ sysbus <0, 1>
mockEnum: 1
";
ProcessSource(source);
Assert.IsTrue(machine.TryGetByName("sysbus.peripheral", out Tests.UnitTests.Mocks.MockPeripheralWithEnumAttribute mockPeripheral));
Assert.AreEqual(MockEnum.ValidValue, mockPeripheral.MockEnumValue);
}
[Test]
public void ShouldFailOnInvalidIntToEnumCast()
{
var source = @"
peripheral: Antmicro.Renode.Tests.UnitTests.Mocks.MockPeripheralWithEnumAttribute
mockEnum: 2
";
var exception = Assert.Throws<ParsingException>(() => ProcessSource(source));
Assert.AreEqual(ParsingError.NoCtor, exception.Error);
}
[Test]
public void ShouldFailOnInvalidIntToEnumWithAttributeCast()
{
var source = @"
peripheral: Antmicro.Renode.Tests.UnitTests.Mocks.MockPeripheralWithEnumAttribute @ sysbus <0, 1>
mockEnumWithAttribute: MockEnumWithAttribute.InvalidValue
";
//ProcessSource(source);
var exception = Assert.Throws<ParsingException>(() => ProcessSource(source));
Assert.AreEqual(ParsingError.NoCtor, exception.Error);
}
[Test]
public void ShouldProcessCastOfAnyIntToEnumWithAttribute()
{
var source = @"
peripheral: Antmicro.Renode.Tests.UnitTests.Mocks.MockPeripheralWithEnumAttribute @ sysbus <0, 1>
mockEnumWithAttribute: 2
";
ProcessSource(source);
Assert.IsTrue(machine.TryGetByName("sysbus.peripheral", out Tests.UnitTests.Mocks.MockPeripheralWithEnumAttribute mockPeripheral));
Assert.AreEqual((MockEnumWithAttribute)2, mockPeripheral.MockEnumWithAttributeValue);
}
[Test]
public void ShouldFailOnAssignmentOfMachineTypeAttribute()
{
var source = @"
peripheral: Antmicro.Renode.Tests.UnitTests.Mocks.MachineTestPeripheral @ sysbus <0, 1>
mach: empty
machine: empty
";
var exception = Assert.Throws<ParsingException>(() => ProcessSource(source));
Assert.AreEqual(ParsingError.NoCtor, exception.Error);
}
[Test]
public void ShouldNotFailOnAssignmentToAttributeWithMachineParameterNameThatIsNotMachine()
{
var source = @"
peripheral: Antmicro.Renode.Tests.UnitTests.Mocks.MachineTestPeripheral @ sysbus <0, 1>
machine: empty
";
Assert.DoesNotThrow(() => ProcessSource(source));
}
[OneTimeSetUp]
public void Init()
{
if(!Misc.TryGetRootDirectory(out var rootDir))
{
throw new ArgumentException("Couldn't get root directory.");
}
TypeManager.Instance.Scan(rootDir);
}
[SetUp]
public void SetUp()
{
machine = new Machine();
EmulationManager.Instance.CurrentEmulation.AddMachine(machine, "machine");
initHandlerMock = new Mock<IInitHandler>();
string nullMessage = null;
initHandlerMock.Setup(x => x.Validate(It.IsAny<IInitable>(), out nullMessage)).Returns(true);
}
[TearDown]
public void TearDown()
{
var currentEmulation = EmulationManager.Instance.CurrentEmulation;
currentEmulation.RemoveMachine(machine);
}
private void ProcessSource(params string[] sources)
{
var letters = Enumerable.Range(0, sources.Length - 1).Select(x => (char)('A' + x)).ToArray();
var usingResolver = new FakeUsingResolver();
for(var i = 1; i < sources.Length; i++)
{
usingResolver.With(letters[i - 1].ToString(), sources[i]);
}
var creationDriver = new CreationDriver(machine, usingResolver, initHandlerMock.Object);
creationDriver.ProcessDescription(sources[0]);
}
private Mock<IInitHandler> initHandlerMock;
private Machine machine;
}
}