Skip to content

Commit

Permalink
Merge pull request #902 from Azure/some-more-testing
Browse files Browse the repository at this point in the history
Some more testing
  • Loading branch information
janboll authored Nov 28, 2024
2 parents 43e8e96 + c934247 commit ebfd27b
Show file tree
Hide file tree
Showing 5 changed files with 218 additions and 26 deletions.
9 changes: 5 additions & 4 deletions tooling/templatize/cmd/pipeline/run/options.go
Original file line number Diff line number Diff line change
Expand Up @@ -97,9 +97,10 @@ func (o *RunOptions) RunPipeline(ctx context.Context) error {
return err
}
return o.PipelineOptions.Pipeline.Run(ctx, &pipeline.PipelineRunOptions{
DryRun: o.DryRun,
Vars: variables,
Region: rolloutOptions.Region,
Step: o.PipelineOptions.Step,
DryRun: o.DryRun,
Vars: variables,
Region: rolloutOptions.Region,
Step: o.PipelineOptions.Step,
SubsciptionLookupFunc: pipeline.LookupSubscriptionID,
})
}
2 changes: 1 addition & 1 deletion tooling/templatize/pkg/pipeline/executiontarget.go
Original file line number Diff line number Diff line change
Expand Up @@ -10,7 +10,7 @@ import (
"github.com/Azure/ARO-HCP/tooling/templatize/pkg/aks"
)

func lookupSubscriptionID(ctx context.Context, subscriptionName string) (string, error) {
func LookupSubscriptionID(ctx context.Context, subscriptionName string) (string, error) {
// Create a new Azure identity client
cred, err := azidentity.NewDefaultAzureCredential(nil)
if err != nil {
Expand Down
42 changes: 21 additions & 21 deletions tooling/templatize/pkg/pipeline/run.go
Original file line number Diff line number Diff line change
Expand Up @@ -39,10 +39,11 @@ func NewPipelineFromFile(pipelineFilePath string, vars config.Variables) (*Pipel
}

type PipelineRunOptions struct {
DryRun bool
Step string
Region string
Vars config.Variables
DryRun bool
Step string
Region string
Vars config.Variables
SubsciptionLookupFunc subsciptionLookup
}

func (p *Pipeline) Run(ctx context.Context, options *PipelineRunOptions) error {
Expand Down Expand Up @@ -70,28 +71,27 @@ func (p *Pipeline) Run(ctx context.Context, options *PipelineRunOptions) error {
}()

for _, rg := range p.ResourceGroups {
err := rg.run(ctx, options)
// prepare execution context
subscriptionID, err := options.SubsciptionLookupFunc(ctx, rg.Subscription)
if err != nil {
return fmt.Errorf("failed to lookup subscription ID for %q: %w", rg.Subscription, err)
}
executionTarget := executionTargetImpl{
subscriptionName: rg.Subscription,
subscriptionID: subscriptionID,
region: options.Region,
resourceGroup: rg.Name,
aksClusterName: rg.AKSCluster,
}
err = rg.run(ctx, options, &executionTarget)
if err != nil {
return err
}
}
return nil
}

func (rg *ResourceGroup) run(ctx context.Context, options *PipelineRunOptions) error {
// prepare execution context
subscriptionID, err := lookupSubscriptionID(ctx, rg.Subscription)
if err != nil {
return err
}
executionTarget := executionTargetImpl{
subscriptionName: rg.Subscription,
subscriptionID: subscriptionID,
region: options.Region,
resourceGroup: rg.Name,
aksClusterName: rg.AKSCluster,
}

func (rg *ResourceGroup) run(ctx context.Context, options *PipelineRunOptions, executionTarget ExecutionTarget) error {
logger := logr.FromContextOrDiscard(ctx)

kubeconfigFile, err := executionTarget.KubeConfig(ctx)
Expand All @@ -101,7 +101,7 @@ func (rg *ResourceGroup) run(ctx context.Context, options *PipelineRunOptions) e
logger.V(5).Error(err, "failed to delete kubeconfig file", "kubeconfig", kubeconfigFile)
}
}()
} else if err != nil || kubeconfigFile == "" && executionTarget.GetAkSClusterName() != "" {
} else if err != nil {
return fmt.Errorf("failed to prepare kubeconfig: %w", err)
}

Expand All @@ -118,7 +118,7 @@ func (rg *ResourceGroup) run(ctx context.Context, options *PipelineRunOptions) e
),
),
kubeconfigFile,
&executionTarget, options,
executionTarget, options,
)
if err != nil {
return err
Expand Down
187 changes: 187 additions & 0 deletions tooling/templatize/pkg/pipeline/run_test.go
Original file line number Diff line number Diff line change
@@ -0,0 +1,187 @@
package pipeline

import (
"context"
"testing"

"gotest.tools/v3/assert"
)

func TestStepRun(t *testing.T) {
fooundOutput := ""
s := &Step{
Name: "test",
Action: "Shell",
Command: []string{"echo", "hello"},
outputFunc: func(output string) {
fooundOutput = output
},
}
err := s.run(context.Background(), "", &executionTargetImpl{}, &PipelineRunOptions{})
assert.NilError(t, err)
assert.Equal(t, fooundOutput, "hello\n")
}

func TestStepRunSkip(t *testing.T) {
s := &Step{
Name: "step",
}
// this should skip
err := s.run(context.Background(), "", &executionTargetImpl{}, &PipelineRunOptions{Step: "skip"})
assert.NilError(t, err)

// this should fail
err = s.run(context.Background(), "", &executionTargetImpl{}, &PipelineRunOptions{Step: "step"})
assert.Error(t, err, "unsupported action type \"\"")
}

func TestRGValidate(t *testing.T) {
testCases := []struct {
name string
rg *ResourceGroup
err string
}{
{
name: "missing name",
rg: &ResourceGroup{},
err: "resource group name is required",
},
{
name: "missing subscription",
rg: &ResourceGroup{Name: "test"},
err: "subscription is required",
},
{
name: "missing dependency",
rg: &ResourceGroup{
Name: "test",
Subscription: "test",
Steps: []*Step{
{
Name: "step2",
DependsOn: []string{"step"},
},
},
},
err: "invalid dependency from step step2 to step",
},
}
for _, tc := range testCases {
t.Run(tc.name, func(t *testing.T) {
err := tc.rg.Validate()
assert.Error(t, err, tc.err)
})
}

}

func TestPipelineValidate(t *testing.T) {
p := &Pipeline{
ResourceGroups: []*ResourceGroup{{}},
}
err := p.Validate()
assert.Error(t, err, "resource group name is required")
}

func TestResourceGroupRun(t *testing.T) {
foundOutput := ""
rg := &ResourceGroup{
Steps: []*Step{
{
Name: "step",
Action: "Shell",
Command: []string{"echo", "hello"},
outputFunc: func(output string) {
foundOutput = output
},
},
},
}
err := rg.run(context.Background(), &PipelineRunOptions{}, &executionTargetImpl{})
assert.NilError(t, err)
assert.Equal(t, foundOutput, "hello\n")
}

func TestResourceGroupError(t *testing.T) {
tmpVals := make([]string, 0)
rg := &ResourceGroup{
Steps: []*Step{
{
Name: "step",
Action: "Shell",
Command: []string{"echo", "hello"},
outputFunc: func(output string) {
tmpVals = append(tmpVals, output)
},
},
{
Name: "step",
Action: "Shell",
Command: []string{"faaaaafffaa"},
outputFunc: func(output string) {
tmpVals = append(tmpVals, output)
},
},
{
Name: "step",
Action: "Shell",
Command: []string{"echo", "hallo"},
outputFunc: func(output string) {
tmpVals = append(tmpVals, output)
},
},
},
}
err := rg.run(context.Background(), &PipelineRunOptions{}, &executionTargetImpl{})
assert.Error(t, err, "failed to execute shell command: exec: \"faaaaafffaa\": executable file not found in $PATH")
// Test processing ends after first error
assert.Equal(t, len(tmpVals), 1)
}

type testExecutionTarget struct{}

func (t *testExecutionTarget) KubeConfig(_ context.Context) (string, error) {
return "", nil
}
func (t *testExecutionTarget) GetSubscriptionID() string { return "test" }
func (t *testExecutionTarget) GetAkSClusterName() string { return "test" }
func (t *testExecutionTarget) GetResourceGroup() string { return "test" }
func (t *testExecutionTarget) GetRegion() string { return "test" }

func TestResourceGroupRunRequireKubeconfig(t *testing.T) {

rg := &ResourceGroup{Steps: []*Step{}}
err := rg.run(context.Background(), &PipelineRunOptions{}, &testExecutionTarget{})
assert.NilError(t, err)
}

func TestPipelineRun(t *testing.T) {
foundOutput := ""
pipeline := &Pipeline{
ResourceGroups: []*ResourceGroup{
{
Name: "test",
Subscription: "test",
Steps: []*Step{
{
Name: "step",
Action: "Shell",
Command: []string{"echo", "hello"},
outputFunc: func(output string) {
foundOutput = output
},
},
},
},
},
}

err := pipeline.Run(context.Background(), &PipelineRunOptions{
SubsciptionLookupFunc: func(_ context.Context, _ string) (string, error) {
return "test", nil
},
})

assert.NilError(t, err)
assert.Equal(t, foundOutput, "hello\n")
}
4 changes: 4 additions & 0 deletions tooling/templatize/pkg/pipeline/types.go
Original file line number Diff line number Diff line change
@@ -1,5 +1,9 @@
package pipeline

import "context"

type subsciptionLookup func(context.Context, string) (string, error)

type Pipeline struct {
pipelineFilePath string
ServiceGroup string `yaml:"serviceGroup"`
Expand Down

0 comments on commit ebfd27b

Please sign in to comment.