1515package functional
1616
1717import (
18+ "encoding/json"
1819 "fmt"
1920 "io/ioutil"
2021 "os"
@@ -26,6 +27,7 @@ import (
2627
2728 "github.com/coreos/fleet/functional/platform"
2829 "github.com/coreos/fleet/functional/util"
30+ "github.com/coreos/fleet/unit"
2931)
3032
3133const (
@@ -772,3 +774,149 @@ func TestReplaceSerialization(t *testing.T) {
772774 os .Remove (tmpSyncFile )
773775 os .Remove (tmpSyncService )
774776}
777+
778+ // TestUnitDestroyFromRegistry() checks for a submitted unit being removed
779+ // from the etcd registry. It compares a local unit body with the unit in
780+ // the etcd registry, to verify the body is identical.
781+ func TestUnitDestroyFromRegistry (t * testing.T ) {
782+ cluster , err := platform .NewNspawnCluster ("smoke" )
783+ if err != nil {
784+ t .Fatal (err )
785+ }
786+ defer cluster .Destroy (t )
787+
788+ m , err := cluster .CreateMember ()
789+ if err != nil {
790+ t .Fatal (err )
791+ }
792+ _ , err = cluster .WaitForNMachines (m , 1 )
793+ if err != nil {
794+ t .Fatal (err )
795+ }
796+
797+ // submit a unit and assert it shows up
798+ if _ , _ , err := cluster .Fleetctl (m , "submit" , "fixtures/units/hello.service" ); err != nil {
799+ t .Fatalf ("Unable to submit fleet unit: %v" , err )
800+ }
801+ stdout , _ , err := cluster .Fleetctl (m , "list-units" , "--no-legend" )
802+ if err != nil {
803+ t .Fatalf ("Failed to run list-units: %v" , err )
804+ }
805+ units := strings .Split (strings .TrimSpace (stdout ), "\n " )
806+ if len (units ) != 1 {
807+ t .Fatalf ("Did not find 1 unit in cluster: \n %s" , stdout )
808+ }
809+
810+ // cat the unit and compare it with the value in etcd registry
811+ unitBody , _ , err := cluster .Fleetctl (m , "cat" , "hello.service" )
812+ if err != nil {
813+ t .Fatalf ("Unable to retrieve the fleet unit: %v" , err )
814+ }
815+
816+ var hashUnit string
817+ if hashUnit , err = retrieveJobObjectHash (cluster , "hello.service" ); err != nil {
818+ t .Fatalf ("Failed to retrieve hash of job object hello.service: %v" , err )
819+ }
820+
821+ var regBody string
822+ if regBody , err = retrieveUnitBody (cluster , hashUnit ); err != nil {
823+ t .Fatalf ("Failed to retrieve unit body for hello.service: %v" , err )
824+ }
825+
826+ // compare it with unitBody
827+ if regBody != unitBody {
828+ t .Fatalf ("Failed to verify fleet unit: %v" , err )
829+ }
830+
831+ // destroy the unit again
832+ if _ , _ , err := cluster .Fleetctl (m , "destroy" , "hello.service" ); err != nil {
833+ t .Fatalf ("Failed to destroy unit: %v" , err )
834+ }
835+
836+ stdout , _ , err = cluster .Fleetctl (m , "list-units" , "--no-legend" )
837+ if err != nil {
838+ t .Fatalf ("Failed to run list-units: %v" , err )
839+ }
840+ units = strings .Split (strings .TrimSpace (stdout ), "\n " )
841+ if len (stdout ) != 0 && len (units ) != 1 {
842+ t .Fatalf ("Did not find 1 unit in cluster: \n %s" , stdout )
843+ }
844+
845+ // check for the unit being destroyed from the etcd registry,
846+ // /fleet_functional/smoke/unit/.
847+ // NOTE: do not check error of etcdctl, as it returns 4 on an empty list.
848+ etcdUnitPrefix := path .Join (cluster .Keyspace (), "unit" )
849+ etcdUnitPath := path .Join (etcdUnitPrefix , hashUnit )
850+ stdout , _ , _ = util .RunEtcdctl ("ls" , etcdUnitPath )
851+ units = strings .Split (strings .TrimSpace (stdout ), "\n " )
852+ if len (stdout ) != 0 && len (units ) != 1 {
853+ t .Fatalf ("The unit still remains in the registry: %v" )
854+ }
855+ }
856+
857+ // retrieveJobObjectHash fetches the job hash value from
858+ // /fleet_functional/smoke/job/<jobName>/object in the etcd registry.
859+ func retrieveJobObjectHash (cluster platform.Cluster , jobName string ) (hash string , err error ) {
860+ etcdJobPrefix := path .Join (cluster .Keyspace (), "job" )
861+ etcdJobPath := path .Join (etcdJobPrefix , jobName , "object" )
862+
863+ var stdout string
864+ if stdout , _ , err = util .RunEtcdctl ("ls" , etcdJobPath ); err != nil {
865+ return "" , fmt .Errorf ("Failed to list a unit from the registry: %v" , err )
866+ }
867+ units := strings .Split (strings .TrimSpace (stdout ), "\n " )
868+ if len (stdout ) == 0 || len (units ) == 0 {
869+ return "" , fmt .Errorf ("No such unit in the registry: %v" , err )
870+ }
871+
872+ stdout , _ , err = util .RunEtcdctl ("get" , etcdJobPath )
873+ stdout = strings .TrimSpace (stdout )
874+ objectBody := strings .Split (stdout , "\n " )
875+ if err != nil || len (stdout ) == 0 || len (objectBody ) == 0 {
876+ return "" , fmt .Errorf ("Failed to get unit from the registry: %v" , err )
877+ }
878+
879+ type jobModel struct {
880+ Name string
881+ UnitHash unit.Hash
882+ }
883+ var jm jobModel
884+ if err = json .Unmarshal ([]byte (stdout ), & jm ); err != nil {
885+ return "" , fmt .Errorf ("Failed to unmarshal fleet unit in the registry: %v" , err )
886+ }
887+
888+ return jm .UnitHash .String (), nil
889+ }
890+
891+ // retrieveUnitBody fetches unit body from /fleet_functional/smoke/unit/<hash>
892+ // in the etcd registry.
893+ func retrieveUnitBody (cluster platform.Cluster , hashUnit string ) (regBody string , err error ) {
894+ etcdUnitPrefix := path .Join (cluster .Keyspace (), "unit" )
895+ etcdUnitPath := path .Join (etcdUnitPrefix , hashUnit )
896+
897+ var stdout string
898+ if stdout , _ , err = util .RunEtcdctl ("ls" , etcdUnitPath ); err != nil {
899+ return "" , fmt .Errorf ("Failed to list a unit from the registry: %v" , err )
900+ }
901+
902+ units := strings .Split (strings .TrimSpace (stdout ), "\n " )
903+ if len (stdout ) == 0 || len (units ) == 0 {
904+ return "" , fmt .Errorf ("No such unit in the registry: %v" , err )
905+ }
906+ stdout , _ , err = util .RunEtcdctl ("get" , etcdUnitPath )
907+ stdout = strings .TrimSpace (stdout )
908+ unitBody := strings .Split (stdout , "\n " )
909+ if err != nil || len (stdout ) == 0 || len (unitBody ) == 0 {
910+ return "" , fmt .Errorf ("Failed to get unit from the registry: %v" , err )
911+ }
912+
913+ type rawModel struct {
914+ Raw string
915+ }
916+
917+ var rm rawModel
918+ if err = json .Unmarshal ([]byte (stdout ), & rm ); err != nil {
919+ return "" , fmt .Errorf ("Failed to unmarshal fleet unit in the registry: %v" , err )
920+ }
921+ return rm .Raw , nil
922+ }
0 commit comments