1+ import * as semver from 'balena-semver' ;
12import _ from 'lodash' ;
23import * as fixtures from './test-lib/fixtures.js' ;
34import * as fakeDevice from './test-lib/fake-device.js' ;
@@ -34,7 +35,7 @@ export default () => {
3435 /* eslint-enable @typescript-eslint/naming-convention */
3536 let rpi3hostAppReleaseId : number ;
3637 let failedIntelNucHostAppReleaseId : number ;
37- let esrTagOnlyHostAppReleaseId : number ;
38+ let esrTagOnlyNonSemverHostAppReleaseId : number ;
3839 let esrUnifiedHostAppReleaseId : number ;
3940 let esrSemverOnlyHostAppReleaseId : number ;
4041 let invalidatedTagOnlyReleaseId : number ;
@@ -63,7 +64,8 @@ export default () => {
6364 nuc2_51_0_rev2prodSemverOnlyId = fx . releases . release2_51_0_rev2 . id ;
6465 rpi3hostAppReleaseId = fx . releases . rpi3release . id ;
6566 failedIntelNucHostAppReleaseId = fx . releases . releaseIntelNucFailed . id ;
66- esrTagOnlyHostAppReleaseId = fx . releases . releaseNucEsrTagOnly . id ;
67+ esrTagOnlyNonSemverHostAppReleaseId =
68+ fx . releases . releaseNucEsrTagOnly . id ;
6769 esrUnifiedHostAppReleaseId = fx . releases . releaseNucEsrUnified . id ;
6870 esrSemverOnlyHostAppReleaseId = fx . releases . releaseNucEsrSemverOnly . id ;
6971 invalidatedTagOnlyReleaseId =
@@ -155,12 +157,12 @@ export default () => {
155157 ( ) => unifiedSemverRevHostAppReleaseId ,
156158 ] ,
157159 [
158- 'ESR release_tag only' ,
160+ 'ESR non-Semver release_tag only' ,
159161 {
160162 os_version : 'balenaOS 2021.01.0' ,
161163 os_variant : 'prod' ,
162164 } ,
163- ( ) => esrTagOnlyHostAppReleaseId ,
165+ ( ) => esrTagOnlyNonSemverHostAppReleaseId ,
164166 ] ,
165167 [
166168 'unified ESR' ,
@@ -435,15 +437,27 @@ export default () => {
435437 'balenaOS 2.51.0+rev2' ,
436438 ( ) => nuc2_51_0_rev2prodSemverOnlyId ,
437439 ] ,
440+ // [
441+ // 'ESR non-Semver release_tag only',
442+ // 'balenaOS 2021.01.0',
443+ // () => esrTagOnlyNonSemverHostAppReleaseId,
444+ // ],
445+ // [
446+ // 'unified ESR',
447+ // 'balenaOS 2023.1.0',
448+ // () => esrUnifiedHostAppReleaseId,
449+ // ],
438450 ] as const
439451 ) . forEach ( ( [ titlePart , osVersion , getReleaseId ] ) => {
440452 it ( `should succeed in PATCHing the device.should_be_operated_by__release to a greater version (with ${ titlePart } )` , async ( ) => {
441453 await supertest ( admin )
442454 . patch ( `/${ version } /device(${ device1 . id } )` )
443455 . send ( { should_be_operated_by__release : getReleaseId ( ) } )
444456 . expect ( 200 ) ;
457+ const initialOsVersion = 'balenaOS 2.49.0+rev1' ;
458+ expect ( semver . gt ( osVersion , initialOsVersion ) ) . to . be . true ;
445459 await expectResourceToMatch ( pineUser , 'device' , device1 . id , {
446- os_version : 'balenaOS 2.49.0+rev1' ,
460+ os_version : initialOsVersion ,
447461 os_variant : 'prod' ,
448462 should_be_operated_by__release : { __id : getReleaseId ( ) } ,
449463 } ) ;
@@ -466,9 +480,11 @@ export default () => {
466480 admin ,
467481 applicationId ,
468482 ) ;
483+ const initialOsVersion = 'balenaOS 2.88.4' ;
484+ expect ( semver . gt ( initialOsVersion , osVersion ) ) . to . be . true ;
469485 await downgradeTestDevice . patchStateV2 ( {
470486 local : {
471- os_version : 'balenaOS 2.88.4' ,
487+ os_version : initialOsVersion ,
472488 os_variant : 'prod' ,
473489 } ,
474490 } ) ;
@@ -510,7 +526,6 @@ export default () => {
510526 applicationId ,
511527 ) ;
512528 await downgradeTestDevice . patchStateV2 ( {
513- // this version is greater than the one provided by prodNucHostappReleaseId
514529 local : {
515530 os_version : osVersion ,
516531 os_variant : 'prod' ,
@@ -525,9 +540,11 @@ export default () => {
525540 } ,
526541 ) ;
527542 // run the actual test
543+ const oldUnkownOsVersion = 'balenaOS 2.9.9+rev99' ;
544+ expect ( semver . gt ( osVersion , oldUnkownOsVersion ) ) . to . be . true ;
528545 await downgradeTestDevice . patchStateV2 ( {
529546 local : {
530- os_version : 'balenaOS 2.9.9+rev99' ,
547+ os_version : oldUnkownOsVersion ,
531548 os_variant : 'prod' ,
532549 } ,
533550 } ) ;
@@ -536,7 +553,7 @@ export default () => {
536553 'device' ,
537554 downgradeTestDevice . id ,
538555 {
539- os_version : 'balenaOS 2.9.9+rev99' ,
556+ os_version : oldUnkownOsVersion ,
540557 os_variant : 'prod' ,
541558 should_be_operated_by__release : { __id : getReleaseId ( ) } ,
542559 } ,
@@ -551,9 +568,11 @@ export default () => {
551568 admin ,
552569 applicationId ,
553570 ) ;
571+ const oldOsVersion = 'balenaOS 2.49.0+rev1' ;
572+ expect ( semver . gt ( osVersion , oldOsVersion ) ) . to . be . true ;
554573 await preprovisionedDevice . patchStateV2 ( {
555574 local : {
556- os_version : 'balenaOS 2.49.0+rev1' ,
575+ os_version : oldOsVersion ,
557576 os_variant : 'prod' ,
558577 } ,
559578 } ) ;
@@ -569,7 +588,6 @@ export default () => {
569588 ) ;
570589 // run the actual test
571590 await preprovisionedDevice . patchStateV2 ( {
572- // this version is greater than the one provided by prodNucHostappReleaseId
573591 local : {
574592 os_version : osVersion ,
575593 os_variant : 'prod' ,
@@ -587,7 +605,7 @@ export default () => {
587605 ) ;
588606 } ) ;
589607
590- it ( `should update the device.should_be_operated_by__release when the state PATCH reports a newer os_version (n a release when with ${ titlePart } )` , async ( ) => {
608+ it ( `should update the device.should_be_operated_by__release when the state PATCH reports a newer os_version (when on a release ${ titlePart } release )` , async ( ) => {
591609 // if a device is preprovisioned and pinned to a release with a semver
592610 // less than the version it initially checks in with, we need to clear
593611 // the old hostApp release, otherwise the model would imply a scheduled OS downgrade.
@@ -596,7 +614,6 @@ export default () => {
596614 applicationId ,
597615 ) ;
598616 await preprovisionedDevice . patchStateV2 ( {
599- // this version is greater than the one provided by prodNucHostappReleaseId
600617 local : {
601618 os_version : osVersion ,
602619 os_variant : 'prod' ,
@@ -610,11 +627,12 @@ export default () => {
610627 should_be_operated_by__release : { __id : getReleaseId ( ) } ,
611628 } ,
612629 ) ;
630+ const newerVersion = 'balenaOS 2.88.4' ;
631+ expect ( semver . gt ( newerVersion , osVersion ) ) . to . be . true ;
613632 // run the actual test
614633 await preprovisionedDevice . patchStateV2 ( {
615- // this version is greater than the one provided by prodNucHostappReleaseId
616634 local : {
617- os_version : 'balenaOS 2.88.4' ,
635+ os_version : newerVersion ,
618636 os_variant : 'prod' ,
619637 } ,
620638 } ) ;
@@ -623,21 +641,69 @@ export default () => {
623641 'device' ,
624642 preprovisionedDevice . id ,
625643 {
626- os_version : 'balenaOS 2.88.4' ,
644+ os_version : newerVersion ,
627645 os_variant : 'prod' ,
628646 should_be_operated_by__release : { __id : unifiedHostAppReleaseId } ,
629647 } ,
630648 ) ;
631649 } ) ;
650+
651+ it ( `should null the device.should_be_operated_by__release when the state PATCH reports a newer "unknown" os_version (when on a release ${ titlePart } release)` , async ( ) => {
652+ // if a device is preprovisioned and pinned to a release with a semver
653+ // less than the version it initially checks in with, we need to clear
654+ // the old hostApp release, otherwise the model would imply a scheduled OS downgrade.
655+ const preprovisionedDevice = await fakeDevice . provisionDevice (
656+ admin ,
657+ applicationId ,
658+ ) ;
659+ await preprovisionedDevice . patchStateV2 ( {
660+ local : {
661+ os_version : osVersion ,
662+ os_variant : 'prod' ,
663+ } ,
664+ } ) ;
665+ await expectResourceToMatch (
666+ pineUser ,
667+ 'device' ,
668+ preprovisionedDevice . id ,
669+ {
670+ should_be_operated_by__release : { __id : getReleaseId ( ) } ,
671+ } ,
672+ ) ;
673+ const newerUnknownVersion = 'balenaOS 100.1.2' ;
674+ expect ( semver . gt ( newerUnknownVersion , osVersion ) ) . to . be . true ;
675+ // run the actual test
676+ await preprovisionedDevice . patchStateV2 ( {
677+ // this is a super new balenaOS version that is greater than the one provided by prodNucHostappReleaseId
678+ local : {
679+ os_version : newerUnknownVersion ,
680+ os_variant : 'prod' ,
681+ } ,
682+ } ) ;
683+ await expectResourceToMatch (
684+ pineUser ,
685+ 'device' ,
686+ preprovisionedDevice . id ,
687+ {
688+ os_version : newerUnknownVersion ,
689+ os_variant : 'prod' ,
690+ should_be_operated_by__release : null ,
691+ } ,
692+ ) ;
693+ } ) ;
632694 } ) ;
633695
634696 it ( 'should succeed in PATCHing device to ESR release' , async ( ) => {
635697 await supertest ( admin )
636698 . patch ( `/${ version } /device(${ device1 . id } )` )
637- . send ( { should_be_operated_by__release : esrTagOnlyHostAppReleaseId } )
699+ . send ( {
700+ should_be_operated_by__release : esrTagOnlyNonSemverHostAppReleaseId ,
701+ } )
638702 . expect ( 200 ) ;
639703 await expectResourceToMatch ( pineUser , 'device' , device1 . id , {
640- should_be_operated_by__release : { __id : esrTagOnlyHostAppReleaseId } ,
704+ should_be_operated_by__release : {
705+ __id : esrTagOnlyNonSemverHostAppReleaseId ,
706+ } ,
641707 } ) ;
642708 } ) ;
643709
0 commit comments