@@ -777,64 +777,67 @@ func TestClearSignatures(t *testing.T) {
777777 assert .Equal (t , []Signature {}, meta .Signatures )
778778}
779779
780- func TestIsExpiredRoot (t * testing.T ) {
781- // without setting expiration
782- meta := Root ()
783- assert .NotNil (t , meta )
784- // ensure time passed
785- time .Sleep (1 * time .Microsecond )
786- assert .True (t , meta .Signed .IsExpired (time .Now ().UTC ()))
787-
788- // setting expiration in 2 days from now
789- expire := time .Now ().AddDate (0 , 0 , 2 ).UTC ()
790- meta = Root (expire )
791- assert .NotNil (t , meta )
792- assert .False (t , meta .Signed .IsExpired (time .Now ().UTC ()))
793- }
794-
795- func TestIsExpiredSnapshot (t * testing.T ) {
796- // without setting expiration
797- meta := Snapshot ()
798- assert .NotNil (t , meta )
799- // ensure time passed
800- time .Sleep (1 * time .Microsecond )
801- assert .True (t , meta .Signed .IsExpired (time .Now ().UTC ()))
802-
803- // setting expiration in 2 days from now
804- expire := time .Now ().AddDate (0 , 0 , 2 ).UTC ()
805- meta = Snapshot (expire )
806- assert .NotNil (t , meta )
807- assert .False (t , meta .Signed .IsExpired (time .Now ().UTC ()))
808- }
809-
810- func TestIsExpiredTimestamp (t * testing.T ) {
811- // without setting expiration
812- meta := Timestamp ()
813- assert .NotNil (t , meta )
814- // ensure time passed
815- time .Sleep (1 * time .Microsecond )
816- assert .True (t , meta .Signed .IsExpired (time .Now ().UTC ()))
817-
818- // setting expiration in 2 days from now
819- expire := time .Now ().AddDate (0 , 0 , 2 ).UTC ()
820- meta = Timestamp (expire )
821- assert .NotNil (t , meta )
822- assert .False (t , meta .Signed .IsExpired (time .Now ().UTC ()))
823- }
824-
825- func TestIsExpiredTargets (t * testing.T ) {
826- // without setting expiration
827- meta := Targets ()
828- assert .NotNil (t , meta )
829- // ensure time passed
830- time .Sleep (1 * time .Microsecond )
831- assert .True (t , meta .Signed .IsExpired (time .Now ().UTC ()))
832-
833- // setting expiration in 2 days from now
834- expire := time .Now ().AddDate (0 , 0 , 2 ).UTC ()
835- meta = Targets (expire )
836- assert .NotNil (t , meta )
837- assert .False (t , meta .Signed .IsExpired (time .Now ().UTC ()))
780+ // TestIsExpiredTable verifies that each top-level role's default-constructed
781+ // metadata is already expired and that a future-dated expiry makes it not
782+ // expired. Replaces the per-role TestIsExpiredRoot/Snapshot/Timestamp/Targets.
783+ func TestIsExpiredTable (t * testing.T ) {
784+ // The closure constructs both metadata copies (default + future-dated) and
785+ // reports whether each is expired relative to a freshly-sampled "now". The
786+ // short sleep guarantees the no-arg constructor's "expires == time.Now()"
787+ // is reliably in the past by the time IsExpired is asked.
788+ tests := []struct {
789+ name string
790+ expirers func (expire time.Time ) (defaultExpired , futureExpired bool )
791+ }{
792+ {
793+ name : "root" ,
794+ expirers : func (expire time.Time ) (bool , bool ) {
795+ def := Root ()
796+ time .Sleep (1 * time .Microsecond )
797+ future := Root (expire )
798+ now := time .Now ().UTC ()
799+ return def .Signed .IsExpired (now ), future .Signed .IsExpired (now )
800+ },
801+ },
802+ {
803+ name : "snapshot" ,
804+ expirers : func (expire time.Time ) (bool , bool ) {
805+ def := Snapshot ()
806+ time .Sleep (1 * time .Microsecond )
807+ future := Snapshot (expire )
808+ now := time .Now ().UTC ()
809+ return def .Signed .IsExpired (now ), future .Signed .IsExpired (now )
810+ },
811+ },
812+ {
813+ name : "timestamp" ,
814+ expirers : func (expire time.Time ) (bool , bool ) {
815+ def := Timestamp ()
816+ time .Sleep (1 * time .Microsecond )
817+ future := Timestamp (expire )
818+ now := time .Now ().UTC ()
819+ return def .Signed .IsExpired (now ), future .Signed .IsExpired (now )
820+ },
821+ },
822+ {
823+ name : "targets" ,
824+ expirers : func (expire time.Time ) (bool , bool ) {
825+ def := Targets ()
826+ time .Sleep (1 * time .Microsecond )
827+ future := Targets (expire )
828+ now := time .Now ().UTC ()
829+ return def .Signed .IsExpired (now ), future .Signed .IsExpired (now )
830+ },
831+ },
832+ }
833+ for _ , tt := range tests {
834+ t .Run (tt .name , func (t * testing.T ) {
835+ expire := time .Now ().AddDate (0 , 0 , 2 ).UTC ()
836+ defaultExpired , futureExpired := tt .expirers (expire )
837+ assert .True (t , defaultExpired , "default-constructed metadata should be expired" )
838+ assert .False (t , futureExpired , "metadata with future expiry should not be expired" )
839+ })
840+ }
838841}
839842
840843func TestUnrecognizedFieldRolesSigned (t * testing.T ) {
@@ -1541,92 +1544,123 @@ func TestCompareFromBytesFromFileToBytes(t *testing.T) {
15411544 assert .Equal (t , stripWhitespaces (timestampBytesWant ), stripWhitespaces (timestampBytesActual ))
15421545}
15431546
1544- func TestRootReadWriteReadCompare (t * testing.T ) {
1545- src := filepath .Join (testutils .RepoDir , "root.json" )
1546- srcRoot , err := Root ().FromFile (src )
1547- assert .NoError (t , err )
1548-
1549- dst := src + ".tmp"
1550- err = srcRoot .ToFile (dst , false )
1551- assert .NoError (t , err )
1552-
1553- dstRoot , err := Root ().FromFile (dst )
1554- assert .NoError (t , err )
1555-
1556- srcBytes , err := srcRoot .ToBytes (false )
1557- assert .NoError (t , err )
1558- dstBytes , err := dstRoot .ToBytes (false )
1559- assert .NoError (t , err )
1560- assert .Equal (t , srcBytes , dstBytes )
1561-
1562- err = os .RemoveAll (dst )
1563- assert .NoError (t , err )
1564- }
1565-
1566- func TestSnapshotReadWriteReadCompare (t * testing.T ) {
1567- path1 := filepath .Join (testutils .RepoDir , "snapshot.json" )
1568- snaphot1 , err := Snapshot ().FromFile (path1 )
1569- assert .NoError (t , err )
1570-
1571- path2 := path1 + ".tmp"
1572- err = snaphot1 .ToFile (path2 , false )
1573- assert .NoError (t , err )
1574-
1575- snapshot2 , err := Snapshot ().FromFile (path2 )
1576- assert .NoError (t , err )
1577-
1578- bytes1 , err := snaphot1 .ToBytes (false )
1579- assert .NoError (t , err )
1580- bytes2 , err := snapshot2 .ToBytes (false )
1581- assert .NoError (t , err )
1582- assert .Equal (t , bytes1 , bytes2 )
1583-
1584- err = os .RemoveAll (path2 )
1585- assert .NoError (t , err )
1586- }
1587-
1588- func TestTargetsReadWriteReadCompare (t * testing.T ) {
1589- path1 := filepath .Join (testutils .RepoDir , "targets.json" )
1590- targets1 , err := Targets ().FromFile (path1 )
1591- assert .NoError (t , err )
1592-
1593- path2 := path1 + ".tmp"
1594- err = targets1 .ToFile (path2 , false )
1595- assert .NoError (t , err )
1596-
1597- targets2 , err := Targets ().FromFile (path2 )
1598- assert .NoError (t , err )
1599-
1600- bytes1 , err := targets1 .ToBytes (false )
1601- assert .NoError (t , err )
1602- bytes2 , err := targets2 .ToBytes (false )
1603- assert .NoError (t , err )
1604- assert .Equal (t , bytes1 , bytes2 )
1605-
1606- err = os .RemoveAll (path2 )
1607- assert .NoError (t , err )
1608- }
1609-
1610- func TestTimestampReadWriteReadCompare (t * testing.T ) {
1611- path1 := filepath .Join (testutils .RepoDir , "timestamp.json" )
1612- timestamp1 , err := Timestamp ().FromFile (path1 )
1613- assert .NoError (t , err )
1614-
1615- path2 := path1 + ".tmp"
1616- err = timestamp1 .ToFile (path2 , false )
1617- assert .NoError (t , err )
1618-
1619- timestamp2 , err := Timestamp ().FromFile (path2 )
1620- assert .NoError (t , err )
1621-
1622- bytes1 , err := timestamp1 .ToBytes (false )
1623- assert .NoError (t , err )
1624- bytes2 , err := timestamp2 .ToBytes (false )
1625- assert .NoError (t , err )
1626- assert .Equal (t , bytes1 , bytes2 )
1547+ // TestRoundtripFileTable verifies that each top-level role's metadata can
1548+ // be read from a fixture file, written back out, re-read, and reproduces
1549+ // identical bytes. Replaces the per-role TestRootReadWriteReadCompare,
1550+ // TestSnapshotReadWriteReadCompare, TestTargetsReadWriteReadCompare,
1551+ // TestTimestampReadWriteReadCompare.
1552+ func TestRoundtripFileTable (t * testing.T ) {
1553+ // roundtrip reads src, writes to dst, reads dst back, and returns the
1554+ // canonical byte form of both copies for comparison.
1555+ tests := []struct {
1556+ name string
1557+ srcRel string
1558+ roundtrip func (src , dst string ) (srcBytes , dstBytes []byte , err error )
1559+ }{
1560+ {
1561+ name : "root" ,
1562+ srcRel : "root.json" ,
1563+ roundtrip : func (src , dst string ) ([]byte , []byte , error ) {
1564+ m , err := Root ().FromFile (src )
1565+ if err != nil {
1566+ return nil , nil , err
1567+ }
1568+ if err := m .ToFile (dst , false ); err != nil {
1569+ return nil , nil , err
1570+ }
1571+ m2 , err := Root ().FromFile (dst )
1572+ if err != nil {
1573+ return nil , nil , err
1574+ }
1575+ a , err := m .ToBytes (false )
1576+ if err != nil {
1577+ return nil , nil , err
1578+ }
1579+ b , err := m2 .ToBytes (false )
1580+ return a , b , err
1581+ },
1582+ },
1583+ {
1584+ name : "snapshot" ,
1585+ srcRel : "snapshot.json" ,
1586+ roundtrip : func (src , dst string ) ([]byte , []byte , error ) {
1587+ m , err := Snapshot ().FromFile (src )
1588+ if err != nil {
1589+ return nil , nil , err
1590+ }
1591+ if err := m .ToFile (dst , false ); err != nil {
1592+ return nil , nil , err
1593+ }
1594+ m2 , err := Snapshot ().FromFile (dst )
1595+ if err != nil {
1596+ return nil , nil , err
1597+ }
1598+ a , err := m .ToBytes (false )
1599+ if err != nil {
1600+ return nil , nil , err
1601+ }
1602+ b , err := m2 .ToBytes (false )
1603+ return a , b , err
1604+ },
1605+ },
1606+ {
1607+ name : "targets" ,
1608+ srcRel : "targets.json" ,
1609+ roundtrip : func (src , dst string ) ([]byte , []byte , error ) {
1610+ m , err := Targets ().FromFile (src )
1611+ if err != nil {
1612+ return nil , nil , err
1613+ }
1614+ if err := m .ToFile (dst , false ); err != nil {
1615+ return nil , nil , err
1616+ }
1617+ m2 , err := Targets ().FromFile (dst )
1618+ if err != nil {
1619+ return nil , nil , err
1620+ }
1621+ a , err := m .ToBytes (false )
1622+ if err != nil {
1623+ return nil , nil , err
1624+ }
1625+ b , err := m2 .ToBytes (false )
1626+ return a , b , err
1627+ },
1628+ },
1629+ {
1630+ name : "timestamp" ,
1631+ srcRel : "timestamp.json" ,
1632+ roundtrip : func (src , dst string ) ([]byte , []byte , error ) {
1633+ m , err := Timestamp ().FromFile (src )
1634+ if err != nil {
1635+ return nil , nil , err
1636+ }
1637+ if err := m .ToFile (dst , false ); err != nil {
1638+ return nil , nil , err
1639+ }
1640+ m2 , err := Timestamp ().FromFile (dst )
1641+ if err != nil {
1642+ return nil , nil , err
1643+ }
1644+ a , err := m .ToBytes (false )
1645+ if err != nil {
1646+ return nil , nil , err
1647+ }
1648+ b , err := m2 .ToBytes (false )
1649+ return a , b , err
1650+ },
1651+ },
1652+ }
1653+ for _ , tt := range tests {
1654+ t .Run (tt .name , func (t * testing.T ) {
1655+ src := filepath .Join (testutils .RepoDir , tt .srcRel )
1656+ dst := src + ".tmp"
1657+ t .Cleanup (func () { _ = os .RemoveAll (dst ) })
16271658
1628- err = os .RemoveAll (path2 )
1629- assert .NoError (t , err )
1659+ a , b , err := tt .roundtrip (src , dst )
1660+ assert .NoError (t , err )
1661+ assert .Equal (t , a , b )
1662+ })
1663+ }
16301664}
16311665
16321666func stripWhitespaces (b []byte ) []byte {
0 commit comments