package tests;
import static org.junit.Assert.assertEquals;
import static org.junit.Assert.assertTrue;
import org.junit.Test;
import models.algebra.Expression;
import models.algebra.InvalidMessage;
import models.algebra.ParameterizedIdentifierIsFutureWork;
import models.algebra.UnificationFailed;
import models.algebra.ValueUndefined;
import models.algebra.Variable;
import models.algebra.Constant;
import models.dataConstraintModel.ChannelMember;
import models.dataConstraintModel.DataConstraintModel;
import models.dataConstraintModel.ResourcePath;
import models.dataFlowModel.DataTransferChannel;
import models.dataFlowModel.DataTransferModel;
import models.dataFlowModel.ResolvingMultipleDefinitionIsFutureWork;
import parser.Parser;
import parser.Parser.TokenStream;
import parser.exceptions.ExpectedColon;
import parser.exceptions.ExpectedDoubleQuotation;
import parser.exceptions.ExpectedRightBracket;
import parser.exceptions.WrongJsonExpression;
import simulator.Event;
import simulator.Resource;
import simulator.Simulator;
import simulator.SystemState;
import simulator.ResourceIdentifier;
import simulator.states.MapResourceState;
public class SimulatorTest {
@Test
public void test() {
try {
TokenStream stream = new Parser.TokenStream();
Parser parser = new Parser(stream);
// Construct a data transfer architecture model.
DataTransferModel model = new DataTransferModel();
ResourcePath customers = new ResourcePath("customers"); // "customers"
ResourcePath customer = new ResourcePath(customers,
new Variable("uid", DataConstraintModel.typeString)); // "customers.{uid}"
ResourcePath customer_off = new ResourcePath(customer, "off"); // "customers.{uid}.off"
ResourcePath customer_add = new ResourcePath(customer, "add"); // "customers.{uid}.add"
ResourcePath companies = new ResourcePath("companies"); // "companies"
ResourcePath company = new ResourcePath(companies,
new Variable("cid", DataConstraintModel.typeString)); // "companies.{cid}"
ResourcePath company_add = new ResourcePath(company, "add"); // "companies.{cid}.add"
ResourcePath company2 = new ResourcePath(companies,
new Variable("cid2", DataConstraintModel.typeString)); // "companies.{cid2}"
ResourcePath company2_add = new ResourcePath(company2, "add"); // "companies.{cid2}.add"
ResourcePath companyA = new ResourcePath(companies,
new Constant("A", DataConstraintModel.typeString)); // "companies.A"
ResourcePath companyA_add = new ResourcePath(companyA, "add"); // "companies.{cid2}.add"
model.addResourcePath(customer_off);
model.addResourcePath(customer_add);
model.addResourcePath(company_add);
model.addResourcePath(company2_add);
model.addResourcePath(customers);
model.addResourcePath(companies);
// For channel CIO_AddCustomer
DataTransferChannel cio_addCustomer = new DataTransferChannel("CIO_AddCustomer"); // add a customer
ChannelMember customers1 = new ChannelMember(customers);
stream.addLine("db:Map");
Expression curStateExp0 = parser.parseTerm(stream, model);
customers1.getStateTransition().setCurStateExpression(curStateExp0);
stream.addLine("addCustomer(uid:Str, off:Str)");
Expression messageExp0 = parser.parseTerm(stream, model);
customers1.getStateTransition().setMessageExpression(messageExp0);
stream.addLine("insert(db, uid, {\"off\": off})");
Expression nextStateExp0 = parser.parseTerm(stream, model);
customers1.getStateTransition().setNextStateExpression(nextStateExp0);
cio_addCustomer.addChannelMemberAsOutput(customers1);
// For channel CIO_AddCompany
DataTransferChannel cio_addCompany = new DataTransferChannel("CIO_AddCompany"); // add a company
ChannelMember companies1 = new ChannelMember(companies);
stream.addLine("db:Map");
Expression curStateExp1 = parser.parseTerm(stream, model);
companies1.getStateTransition().setCurStateExpression(curStateExp1);
stream.addLine("addCampany(cid:Str, add:Str)");
Expression messageExp1 = parser.parseTerm(stream, model);
companies1.getStateTransition().setMessageExpression(messageExp1);
stream.addLine("insert(db, cid, {\"add\": add})");
Expression nextStateExp1 = parser.parseTerm(stream, model);
companies1.getStateTransition().setNextStateExpression(nextStateExp1);
cio_addCompany.addChannelMemberAsOutput(companies1);
// For channel CIO_SetCustomerOff
DataTransferChannel cio_setCustomerOff = new DataTransferChannel("CIO_SetCustomerOff", new Variable("uid")); // set customer's office
ChannelMember customer_off_1 = new ChannelMember(customer_off);
stream.addLine("cid:Str");
Expression curStateExp2 = parser.parseTerm(stream, model);
customer_off_1.getStateTransition().setCurStateExpression(curStateExp2);
stream.addLine("setOff(cid2:Str)");
Expression messageExp2 = parser.parseTerm(stream, model);
customer_off_1.getStateTransition().setMessageExpression(messageExp2);
stream.addLine("cid2");
Expression nextStateExp2 = parser.parseTerm(stream, model);
customer_off_1.getStateTransition().setNextStateExpression(nextStateExp2);
cio_setCustomerOff.addChannelMemberAsOutput(customer_off_1);
// For channel CIO_SetCompanyAdd
DataTransferChannel cio_setCompanyAdd = new DataTransferChannel("CIO_SetCompanyAdd", new Variable("cid")); // set companie's address
ChannelMember company_add_1 = new ChannelMember(company_add);
stream.addLine("a1:Str");
Expression curStateExp3 = parser.parseTerm(stream, model);
company_add_1.getStateTransition().setCurStateExpression(curStateExp3);
stream.addLine("setAdd(a2:Str)");
Expression messageExp3 = parser.parseTerm(stream, model);
company_add_1.getStateTransition().setMessageExpression(messageExp3);
stream.addLine("a2");
Expression nextStateExp3 = parser.parseTerm(stream, model);
company_add_1.getStateTransition().setNextStateExpression(nextStateExp3);
cio_setCompanyAdd.addChannelMemberAsOutput(company_add_1);
// For channel C
DataTransferChannel c = new DataTransferChannel("C", new Variable("uid")); // update customer's address
ChannelMember customer_off_2 = new ChannelMember(customer_off);
stream.addLine("cid:Str");
Expression curStateExp4 = parser.parseTerm(stream, model);
customer_off_2.getStateTransition().setCurStateExpression(curStateExp4);
stream.addLine("sync(cid2:Str, add2:Str)");
Expression messageExp4 = parser.parseTerm(stream, model);
customer_off_2.getStateTransition().setMessageExpression(messageExp4);
stream.addLine("cid2");
Expression nextStateExp4 = parser.parseTerm(stream, model);
customer_off_2.getStateTransition().setNextStateExpression(nextStateExp4);
c.addChannelMemberAsInput(customer_off_2);
ChannelMember company_add_2 = new ChannelMember(company2_add);
stream.addLine("a1:Str");
Expression curStateExp5 = parser.parseTerm(stream, model);
company_add_2.getStateTransition().setCurStateExpression(curStateExp5);
stream.addLine("sync(cid2:Str, add2:Str)");
Expression messageExp5 = parser.parseTerm(stream, model);
company_add_2.getStateTransition().setMessageExpression(messageExp5);
stream.addLine("add2");
Expression nextStateExp5 = parser.parseTerm(stream, model);
company_add_2.getStateTransition().setNextStateExpression(nextStateExp5);
c.addChannelMemberAsInput(company_add_2);
ChannelMember customer_add_2 = new ChannelMember(customer_add);
stream.addLine("a3:Str");
Expression curStateExp6 = parser.parseTerm(stream, model);
customer_add_2.getStateTransition().setCurStateExpression(curStateExp6);
stream.addLine("sync(cid2:Str, add2:Str)");
Expression messageExp6 = parser.parseTerm(stream, model);
customer_add_2.getStateTransition().setMessageExpression(messageExp6);
stream.addLine("add2");
Expression nextStateExp6 = parser.parseTerm(stream, model);
customer_add_2.getStateTransition().setNextStateExpression(nextStateExp6);
c.addChannelMemberAsOutput(customer_add_2);
model.addInputChannel(cio_addCustomer);
model.addInputChannel(cio_addCompany);
model.addInputChannel(cio_setCustomerOff);
model.addInputChannel(cio_setCompanyAdd);
model.addChannel(c);
Simulator simulator = new Simulator(model);
// Initial state
SystemState initialState = simulator.init();
assertEquals(2, initialState.getRootResources().size());
for (Resource rootRes: initialState.getRootResources()) {
assertTrue(rootRes.getState() instanceof MapResourceState);
assertEquals(0, rootRes.getChildren().size());
assertEquals(0, ((MapResourceState) rootRes.getState()).getChildStates().size());
}
System.out.println("companies:" + initialState.getResource(ResourceIdentifier.createFrom(companies)).getState().getValue());
System.out.println("customers:" + initialState.getResource(ResourceIdentifier.createFrom(customers)).getState().getValue());
// Next state (companies.addCompany("A", "Osaka"))
stream.addLine("addCompany(\"A\", \"Osaka\")");
Expression messageAddComp = parser.parseTerm(stream, model);
Event addCompany = new Event(cio_addCompany, messageAddComp, companies, initialState.getResource(ResourceIdentifier.createFrom(companies)));
simulator.transition(addCompany);
SystemState nextState = simulator.getCurState();
assertEquals(2, nextState.getRootResources().size());
Resource companiesRes = nextState.getResource(ResourceIdentifier.createFrom(companies));
assertTrue(companiesRes.getState() instanceof MapResourceState);
assertEquals(1, companiesRes.getChildren().size());
assertEquals(1, ((MapResourceState) companiesRes.getState()).getChildStates().size());
System.out.println("companies:" + nextState.getResource(ResourceIdentifier.createFrom(companies)).getState().getValue());
System.out.println("customers:" + nextState.getResource(ResourceIdentifier.createFrom(customers)).getState().getValue());
// After the next state (customers.addCustomer("1", "A"))
stream.addLine("addCustomer(\"1\", \"A\")");
Expression messageAddCust = parser.parseTerm(stream, model);
Event addCustomer = new Event(cio_addCustomer, messageAddCust, customers, nextState.getResource(ResourceIdentifier.createFrom(customers)));
simulator.transition(addCustomer);
SystemState nextNextState = simulator.getCurState();
assertEquals(2, nextState.getRootResources().size());
Resource customersRes = nextNextState.getResource(ResourceIdentifier.createFrom(customers));
assertTrue(customersRes.getState() instanceof MapResourceState);
assertEquals(1, customersRes.getChildren().size());
assertEquals(1, ((MapResourceState) customersRes.getState()).getChildStates().size());
System.out.println("companies:" + nextNextState.getResource(ResourceIdentifier.createFrom(companies)).getState().getValue());
System.out.println("customers:" + nextNextState.getResource(ResourceIdentifier.createFrom(customers)).getState().getValue());
// After the next next state (companies.A.setAdd("Tokyo"))
stream.addLine("setAdd(\"Tokyo\")");
Expression messageSetAdd = parser.parseTerm(stream, model);
Event setAdd = new Event(cio_setCompanyAdd, messageSetAdd, company_add, nextNextState.getResource(ResourceIdentifier.createFrom(companyA_add)));
simulator.transition(setAdd);
SystemState nextNextNextState = simulator.getCurState();
Resource customersRes2 = nextNextNextState.getResource(ResourceIdentifier.createFrom(customers));
assertTrue(customersRes2.getState() instanceof MapResourceState);
assertEquals(1, customersRes2.getChildren().size());
assertEquals(1, ((MapResourceState) customersRes2.getState()).getChildStates().size());
System.out.println("companies:" + nextNextNextState.getResource(ResourceIdentifier.createFrom(companies)).getState().getValue());
System.out.println("customers:" + nextNextNextState.getResource(ResourceIdentifier.createFrom(customers)).getState().getValue());
} catch (ExpectedRightBracket | WrongJsonExpression | ExpectedColon | ParameterizedIdentifierIsFutureWork | ResolvingMultipleDefinitionIsFutureWork | InvalidMessage | UnificationFailed | ValueUndefined | ExpectedDoubleQuotation e) {
e.printStackTrace();
}
}
}