github.com/Axway/agent-sdk@v1.1.101/pkg/migrate/apisimigration_test.go (about)

     1  package migrate
     2  
     3  import (
     4  	"context"
     5  	"fmt"
     6  	"math/rand"
     7  	"sync"
     8  	"testing"
     9  
    10  	apiv1 "github.com/Axway/agent-sdk/pkg/apic/apiserver/models/api/v1"
    11  	management "github.com/Axway/agent-sdk/pkg/apic/apiserver/models/management/v1alpha1"
    12  	"github.com/Axway/agent-sdk/pkg/apic/definitions"
    13  	"github.com/Axway/agent-sdk/pkg/config"
    14  	"github.com/Axway/agent-sdk/pkg/util"
    15  	"github.com/stretchr/testify/assert"
    16  )
    17  
    18  var defEnvName = config.NewTestCentralConfig(config.DiscoveryAgent).GetEnvironmentName()
    19  
    20  func createInstanceResponse(serviceName string, numRevs int) []*apiv1.ResourceInstance {
    21  	insts := []*apiv1.ResourceInstance{}
    22  	for i := 1; i <= numRevs; i++ {
    23  		inst := management.NewAPIServiceInstance(fmt.Sprintf("%v.%v", serviceName, i), defEnvName)
    24  		inst.Spec.ApiServiceRevision = fmt.Sprintf("%v.%v", serviceName, i)
    25  
    26  		ri, _ := inst.AsInstance()
    27  		insts = append(insts, ri)
    28  	}
    29  
    30  	rand.Shuffle(len(insts), func(i, j int) {
    31  		insts[i], insts[j] = insts[j], insts[i]
    32  	})
    33  
    34  	return insts
    35  }
    36  
    37  func TestAPISIMigration(t *testing.T) {
    38  	tests := []struct {
    39  		name              string
    40  		resource          apiv1.Interface
    41  		expectErr         bool
    42  		turnOff           bool
    43  		migrationComplete bool
    44  		setMigCompelete   bool
    45  		instances         []*apiv1.ResourceInstance
    46  		expectedDeletes   int
    47  	}{
    48  		{
    49  			name:     "called with non-apiservice returns without error",
    50  			resource: management.NewAccessRequestDefinition("asdf", defEnvName),
    51  		},
    52  		{
    53  			name:     "called with apiservice and config off returns without error",
    54  			resource: management.NewAPIService("asdf", defEnvName),
    55  			turnOff:  true,
    56  		},
    57  		{
    58  			name:              "called with apiservice that previously was migrated",
    59  			resource:          management.NewAPIService("asdf", defEnvName),
    60  			setMigCompelete:   true,
    61  			migrationComplete: true,
    62  		},
    63  		{
    64  			name:              "called with apiservice and with no instances returns without error",
    65  			resource:          management.NewAPIService("asdf", defEnvName),
    66  			migrationComplete: true,
    67  		},
    68  		{
    69  			name:              "called with apiservice and instances of same stage returns without error",
    70  			resource:          management.NewAPIService("apisi", defEnvName),
    71  			instances:         createInstanceResponse("apisi", 10),
    72  			expectedDeletes:   9,
    73  			migrationComplete: true,
    74  		},
    75  		{
    76  			name:              "called with apiservice and instances of diff stages returns without error",
    77  			resource:          management.NewAPIService("apisi", defEnvName),
    78  			instances:         append(createInstanceResponse("apisi-stage1", 5), createInstanceResponse("apisi-stage2", 5)...),
    79  			expectedDeletes:   8,
    80  			migrationComplete: true,
    81  		},
    82  	}
    83  
    84  	for _, tt := range tests {
    85  		t.Run(tt.name, func(t *testing.T) {
    86  			c := &mockAPISIMigClient{
    87  				instances: tt.instances,
    88  			}
    89  
    90  			cfg := config.NewTestCentralConfig(config.DiscoveryAgent)
    91  			cfg.(*config.CentralConfiguration).MigrationSettings.(*config.MigrationSettings).CleanInstances = !tt.turnOff
    92  			mig := NewAPISIMigration(c, cfg)
    93  
    94  			resInst, _ := tt.resource.AsInstance()
    95  			if tt.setMigCompelete {
    96  				util.SetAgentDetailsKey(resInst, definitions.InstanceMigration, definitions.MigrationCompleted)
    97  			}
    98  			ri, err := mig.Migrate(context.Background(), resInst)
    99  			if tt.expectErr {
   100  				assert.NotNil(t, err)
   101  				return
   102  			}
   103  
   104  			assert.Nil(t, err)
   105  			migVal, _ := util.GetAgentDetailsValue(ri, definitions.InstanceMigration)
   106  			if tt.migrationComplete {
   107  				assert.Equal(t, definitions.MigrationCompleted, migVal)
   108  			} else {
   109  				assert.Equal(t, "", migVal)
   110  			}
   111  			assert.Equal(t, tt.expectedDeletes, c.deleteCalls)
   112  		})
   113  	}
   114  }
   115  
   116  type mockAPISIMigClient struct {
   117  	sync.Mutex
   118  	deleteCalls      int
   119  	instances        []*apiv1.ResourceInstance
   120  	instanceReturned bool
   121  }
   122  
   123  func (m *mockAPISIMigClient) ExecuteAPI(method, url string, queryParam map[string]string, buffer []byte) ([]byte, error) {
   124  	return nil, nil
   125  }
   126  
   127  func (m *mockAPISIMigClient) GetAPIV1ResourceInstances(query map[string]string, url string) ([]*apiv1.ResourceInstance, error) {
   128  	m.Lock()
   129  	defer m.Unlock()
   130  	if m.instanceReturned {
   131  		return nil, nil
   132  	}
   133  	m.instanceReturned = true
   134  	return m.instances, nil
   135  }
   136  
   137  func (m *mockAPISIMigClient) UpdateResourceInstance(ri apiv1.Interface) (*apiv1.ResourceInstance, error) {
   138  	r, err := ri.AsInstance()
   139  	return r, err
   140  }
   141  
   142  func (m *mockAPISIMigClient) CreateOrUpdateResource(data apiv1.Interface) (*apiv1.ResourceInstance, error) {
   143  	return nil, nil
   144  }
   145  
   146  func (m *mockAPISIMigClient) CreateSubResource(rm apiv1.ResourceMeta, subs map[string]interface{}) error {
   147  	return nil
   148  }
   149  
   150  func (m *mockAPISIMigClient) DeleteResourceInstance(ri apiv1.Interface) error {
   151  	m.deleteCalls++
   152  	return nil
   153  }
   154  
   155  func (m *mockAPISIMigClient) GetResource(url string) (*apiv1.ResourceInstance, error) {
   156  	return nil, nil
   157  }