Skip to content

Add idempotency regression tests for disk/API sync flow #79

@BoBiene

Description

@BoBiene

Summary

Add unit/integration-style regression tests to verify that the sync model, disk serialization, and compare/apply logic are idempotent and do not re-detect changes after a no-op roundtrip.

This is intended to validate and protect against the behavior reported in #78, where KepwareToDiskAndSecondary can enter a repeated sync loop when changes written from disk to Kepware are immediately detected again as fresh changes.

Problem

The current sync flow can enqueue a follow-up PrimaryKepServer sync after a Disk -> Primary sync when changes were applied. That behavior is only safe if the full roundtrip is idempotent.

If any representation difference remains between:

  • in-memory model
  • YAML/CSV persisted representation
  • reloaded model
  • compare/apply input vs API-loaded state

then the next sync cycle may still detect differences and trigger another update, causing a feedback loop.

We need tests that verify:

  1. whether the roundtrip is actually stable
  2. that once a change has been applied, a second run with the same effective data produces no further changes
  3. that future changes do not reintroduce this regression

Goal

Create regression tests that prove the synchronization pipeline is idempotent for unchanged data and does not continuously produce false-positive updates.

Scope

Add tests for the following areas:

1. YAML roundtrip stability

Verify that serializing and deserializing entities does not introduce semantic changes.

Suggested coverage:

  • Project
  • Channel
  • Device
  • DeviceTagGroup (if practical)
  • Tag where applicable through CSV path

Suggested assertions:

  • important fields remain equal after roundtrip
  • Hash remains stable after roundtrip
  • re-saving the same object does not change the persisted output

2. CSV tag roundtrip stability

Verify that exporting/importing tags via CsvTagSerializer preserves effective values and does not change tag hashes unexpectedly.

Suggested assertions:

  • imported tags match exported tag values
  • imported tags do not create false-positive compare/update results
  • numeric/bool/string fields preserve their intended types/values

3. Project storage roundtrip idempotency

Verify the KepFolderStorage roundtrip:

Project -> ExportProjecAsync -> LoadProject(true)

Suggested assertions:

  • loaded project is semantically equivalent to the exported project
  • a second export/load cycle does not introduce additional differences
  • compare logic against the same effective project reports no updates/inserts/deletes

4. Compare/apply idempotency regression test

Verify that once a source project has been applied, repeating compare/apply with the same effective input does not produce further changes.

Suggested assertions:

  • first compare/apply may report changes
  • second compare/apply against the already-updated target reports zero changes
  • no repeated updates are triggered by representation-only differences

5. Sync loop regression protection

Add a targeted regression test around the sync behavior that models:

  • local file sync applies changes
  • a follow-up sync from primary occurs
  • no further effective changes exist
  • no repeated change cascade occurs

This test can be mock-based if a full integration test is too heavy.

Suggested test cases

A. YAML serializer roundtrip preserves entity hash

Examples:

  • YamlSerializer_Roundtrip_Channel_ShouldPreserveHash
  • YamlSerializer_Roundtrip_Device_ShouldPreserveHash

B. CSV serializer roundtrip preserves tag semantics

Examples:

  • CsvTagSerializer_Roundtrip_Tag_ShouldPreserveEffectiveValues
  • CsvTagSerializer_Roundtrip_Tags_ShouldNotIntroduceHashDifferences

C. Project storage roundtrip is idempotent

Examples:

  • KepFolderStorage_ProjectRoundtrip_ShouldBeIdempotent
  • KepFolderStorage_SecondRoundtrip_ShouldProduceNoFurtherDifferences

D. Compare/apply becomes stable after first application

Examples:

  • CompareAndApply_SameEffectiveProject_SecondRun_ShouldReportNoChanges
  • CompareAndApply_RoundtripReloadedProject_ShouldReportNoChanges

E. Sync service does not re-trigger indefinitely

Examples:

  • SyncService_DiskToPrimaryFollowedByPrimarySync_ShouldNotLoopWhenNoEffectiveChangesRemain

Implementation notes

Please pay particular attention to fields that are likely to differ only by representation, for example:

  • numeric type conversions (int, long, etc.)
  • boolean conversions
  • absent vs default-valued dynamic properties
  • YAML/CSV normalization differences
  • property ordering / normalization behavior
  • values introduced or omitted by cleanup/serialization

Acceptance criteria

  • Add regression tests covering serializer and storage roundtrips
  • Add regression tests covering compare/apply idempotency
  • Add at least one test specifically designed to guard against the sync feedback-loop pattern from Continuous/Infinite Sync Loop when using KepwareToDiskAndSecondary direction #78
  • Tests fail if a no-op roundtrip introduces false-positive updates
  • Tests pass when unchanged effective configuration remains stable across repeated sync cycles

Related

Metadata

Metadata

Labels

choreMaintenance tasks, e.g., dependency updates

Type

Projects

No projects

Milestone

No milestone

Relationships

None yet

Development

No branches or pull requests

Issue actions