A – Registration and execution - Register GenesisCommunication Factory in the component list. - Separate the Genesis form and sequence from iPerl communication. B – Communication activities - Restore initialization, connection, PCB reading, password and login. - Include grouped login, mode switching and disconnection. - Support processing up to 10 slots. C1 – Input calibration factors - Read three factors from Water meters / Text1–Text3. - Validate integer values in the range 1–65535. - Preserve the default of 15625 when all three fields are empty. D – Q3 calibration - Connect the Prepare Q3 → measurement → Write Q3 workflow. - Add channel processing to FlyingStart and FlyingStartMassCollection. - Reset previous measurement data and validate calculated factors. - Mark factors as stored only after StoreCalibration succeeds. E – Results and database - Store calibration factors separately for each meter and channel. - Add result entities, mappings and Q3 data. - Extend DB.cs / EnsureSchema to create and update the schema. - Preserve compatibility with the existing binary format. Validation: - Debug build and 18 tests passed. - Simulated communication runs follow the same activity sequence. - The complete Q3 workflow has not yet been verified on hardware. Known limitation: - An inherited mismatch in simulated responses and error propagation can produce an incorrect OK result; this change does not fix it.
180 lines
9.1 KiB
C#
180 lines
9.1 KiB
C#
using System;
|
|
using System.Data.SQLite;
|
|
using System.IO;
|
|
using Microsoft.VisualStudio.TestTools.UnitTesting;
|
|
using Results.Entities;
|
|
using Results.Entities.helpers;
|
|
using GenesisCalibrationFactors = TBF.Rig.TestMethods.GenesisCommunication.GenesisCalibrationFactors;
|
|
|
|
namespace TBFTests
|
|
{
|
|
[TestClass]
|
|
public class GenesisRecoveryTests
|
|
{
|
|
[TestMethod]
|
|
public void TextFieldsPreserveConfiguredFactors()
|
|
{
|
|
double[] factors; string error;
|
|
Assert.IsTrue(GenesisCalibrationFactors.TryParse("17969", "17969", "17969", out factors, out error));
|
|
CollectionAssert.AreEqual(new double[] { 17969, 17969, 17969 }, factors);
|
|
Assert.IsTrue(GenesisCalibrationFactors.TryParse(" 17969 ", "18000", "19000", out factors, out error));
|
|
CollectionAssert.AreEqual(new double[] { 17969, 18000, 19000 }, factors);
|
|
}
|
|
|
|
[TestMethod]
|
|
public void IncompleteOrInvalidFactorsAreRejectedBeforeWriting()
|
|
{
|
|
foreach (var invalid in new[] { null, "", "0", "-1", "65536", "NaN", "1.5", "bad" })
|
|
{
|
|
double[] factors; string error;
|
|
Assert.IsFalse(GenesisCalibrationFactors.TryParse("17969", invalid, "17969", out factors, out error));
|
|
Assert.IsNull(factors);
|
|
StringAssert.Contains(error, "Text2");
|
|
}
|
|
}
|
|
|
|
[TestMethod]
|
|
public void EmptyLegacyConfigurationKeepsDefault()
|
|
{
|
|
double[] factors; string error;
|
|
Assert.IsTrue(GenesisCalibrationFactors.TryParse(null, " ", "", out factors, out error));
|
|
CollectionAssert.AreEqual(new double[] { 15625, 15625, 15625 }, factors);
|
|
}
|
|
|
|
[TestMethod]
|
|
public void MultipleMetersHaveIndependentStableChannelRecords()
|
|
{
|
|
var test = new TestRslt();
|
|
var first = new WaterMeter { WMPosition = 1 };
|
|
var second = new WaterMeter { WMPosition = 2 };
|
|
var a = test.GetCalibrationFactors(first);
|
|
var b = test.GetCalibrationFactors(second);
|
|
a[0].BaseCalibFactor = 17969;
|
|
b[0].BaseCalibFactor = 19000;
|
|
Assert.AreEqual(6, test.CalibFactorResultsToSave.Count);
|
|
Assert.AreSame(a[0], test.GetCalibrationFactors(first)[0]);
|
|
Assert.AreEqual(17969, a[0].BaseCalibFactor);
|
|
Assert.AreEqual(19000, b[0].BaseCalibFactor);
|
|
for (int i = 0; i < 3; i++) Assert.AreEqual(i + 1, b[i].CalibFactorIndex);
|
|
}
|
|
|
|
[TestMethod]
|
|
public void GenesisFactoryAndProcedureActivitiesAreAvailable()
|
|
{
|
|
var factory = TBF.Rig.TbfComponents.CmpntFactoryFromClassName("TestMethods.GenesisCommunication");
|
|
Assert.IsNotNull(factory);
|
|
var config = factory.DefaultConfig() as TBF.Rig.TestMethods.GenesisCommunication.TestMethodCfg;
|
|
Assert.IsNotNull(config);
|
|
Assert.AreEqual(10, config.NrThreads);
|
|
var parameters = new TBF.Rig.TestMethods.GenesisCommunication.iPerlCommunicationParams(true);
|
|
CollectionAssert.Contains(new System.Collections.Generic.List<string>(parameters.ParamValues(0)), "Prepare Q3 Calibration Slot");
|
|
Assert.IsNotNull(TBF.Rig.TbfComponents.CmpntFactoryFromClassName("TestMethods.iPerlCommunication"));
|
|
}
|
|
|
|
[TestMethod]
|
|
public void MappedCalibrationRecordsRoundTripForTwoMeters()
|
|
{
|
|
string path = Path.Combine(Path.GetTempPath(), "genesis-roundtrip-" + Guid.NewGuid() + ".sqlite");
|
|
var previousType = Results.DB.DbType;
|
|
var previousConnection = Results.DB.ConnectionString;
|
|
var previousFactory = Results.DB.SessionFactory;
|
|
try
|
|
{
|
|
Results.DB.DbType = Common.DBType.SQLite;
|
|
Results.DB.ConnectionString = path;
|
|
using (var factory = Results.DB.CreateSessionFactory(true))
|
|
{
|
|
int testId;
|
|
using (var session = factory.OpenSession())
|
|
using (var transaction = session.BeginTransaction())
|
|
{
|
|
var test = new TestRslt();
|
|
session.Save(test);
|
|
testId = test.Id;
|
|
for (int meter = 1; meter <= 2; meter++)
|
|
foreach (var factor in test.GetCalibrationFactors(new WaterMeter { WMPosition = meter }))
|
|
{
|
|
factor.BaseCalibFactor = 17969 + meter;
|
|
factor.CalculatedCalibFactor = 18000 + meter;
|
|
factor.Stored = true;
|
|
factor.IsCalibFactorValid = true;
|
|
session.Save(factor);
|
|
}
|
|
transaction.Commit();
|
|
}
|
|
DatabaseMigrationHelper.EnsureSchema(Common.DBType.SQLite, path);
|
|
using (var session = factory.OpenSession())
|
|
{
|
|
var rows = TestRsltCalibFactorHelper.GetByTestRsltId(session, testId);
|
|
Assert.AreEqual(6, rows.Count);
|
|
foreach (var row in rows)
|
|
{
|
|
Assert.AreEqual(17969 + row.WaterMeterPosition, row.BaseCalibFactor);
|
|
Assert.IsTrue(row.Stored);
|
|
Assert.IsTrue(row.IsCalibFactorValid);
|
|
}
|
|
}
|
|
}
|
|
}
|
|
finally
|
|
{
|
|
Results.DB.DbType = previousType;
|
|
Results.DB.ConnectionString = previousConnection;
|
|
Results.DB.SessionFactory = previousFactory;
|
|
SQLiteConnection.ClearAllPools();
|
|
if (File.Exists(path)) File.Delete(path);
|
|
}
|
|
}
|
|
|
|
// This test creates a temporary schema at runtime; no IDE data source exists.
|
|
// ReSharper disable SqlResolve
|
|
[TestMethod]
|
|
public void SQLiteEnsureCreatesAndUpgradesWithoutLosingExistingData()
|
|
{
|
|
string path = Path.Combine(Path.GetTempPath(), "genesis-migration-" + Guid.NewGuid() + ".sqlite");
|
|
try
|
|
{
|
|
using (var connection = new SQLiteConnection("Data Source=" + path))
|
|
{
|
|
connection.Open();
|
|
Execute(connection, "CREATE TABLE WaterMeterData(Id INTEGER PRIMARY KEY)");
|
|
Execute(connection, "CREATE TABLE WaterMeter(Id INTEGER PRIMARY KEY, CalibFactorNominal REAL NOT NULL DEFAULT 4096)");
|
|
Execute(connection, "CREATE TABLE MeterTestRslt(Id INTEGER PRIMARY KEY, FlipMode INT NULL)");
|
|
Execute(connection, "INSERT INTO WaterMeter(Id, CalibFactorNominal) VALUES(1, 17969)");
|
|
Execute(connection, "INSERT INTO MeterTestRslt(Id, FlipMode) VALUES(1, 7)");
|
|
// Simulate a partially migrated database from a previous special build.
|
|
Execute(connection, "CREATE TABLE TestRsltCalibFactor(Id INTEGER PRIMARY KEY, TestRsltId INT)");
|
|
Execute(connection, "INSERT INTO TestRsltCalibFactor(Id, TestRsltId) VALUES(1, 12)");
|
|
}
|
|
DatabaseMigrationHelper.EnsureSchema(Common.DBType.SQLite, path);
|
|
DatabaseMigrationHelper.EnsureSchema(Common.DBType.SQLite, path);
|
|
using (var connection = new SQLiteConnection("Data Source=" + path))
|
|
{
|
|
connection.Open();
|
|
Assert.AreEqual(17969d, Convert.ToDouble(Scalar(connection, "SELECT CalibFactorNominal FROM WaterMeter WHERE Id=1")));
|
|
Assert.AreEqual(7L, Convert.ToInt64(Scalar(connection, "SELECT FlipMode FROM MeterTestRslt WHERE Id=1")));
|
|
Assert.AreEqual(0L, Convert.ToInt64(Scalar(connection, "SELECT Q3Channel FROM WaterMeter WHERE Id=1")));
|
|
Assert.AreEqual(12L, Convert.ToInt64(Scalar(connection, "SELECT TestRsltId FROM TestRsltCalibFactor WHERE Id=1")));
|
|
Execute(connection, "UPDATE TestRsltCalibFactor SET WaterMeterPosition=2, CalibFactorIndex=3, BaseCalibFactor=17969, IsCalibFactorValid=1, Stored=1 WHERE Id=1");
|
|
Assert.AreEqual(17969L, Convert.ToInt64(Scalar(connection, "SELECT BaseCalibFactor FROM TestRsltCalibFactor WHERE WaterMeterPosition=2 AND CalibFactorIndex=3")));
|
|
Assert.AreEqual(0L, Convert.ToInt64(Scalar(connection, "SELECT COUNT(*) FROM MeterTestCalibFactorRslt")));
|
|
}
|
|
}
|
|
finally { SQLiteConnection.ClearAllPools(); if (File.Exists(path)) File.Delete(path); }
|
|
}
|
|
|
|
// ReSharper restore SqlResolve
|
|
|
|
private static void Execute(SQLiteConnection connection, string sql)
|
|
{
|
|
using (var command = connection.CreateCommand()) { command.CommandText = sql; command.ExecuteNonQuery(); }
|
|
}
|
|
|
|
private static object Scalar(SQLiteConnection connection, string sql)
|
|
{
|
|
using (var command = connection.CreateCommand()) { command.CommandText = sql; return command.ExecuteScalar(); }
|
|
}
|
|
}
|
|
}
|
|
|