Skip to content

Commit dec4868

Browse files
authored
Fix for demo extension + funct tests (#6258)
* Fix missing mapper and add functional sample for demo ext to build and publish container * functional tests using demo extension
1 parent 252aac4 commit dec4868

File tree

11 files changed

+2397
-1
lines changed

11 files changed

+2397
-1
lines changed

cli/azd/pkg/project/mapper_registry.go

Lines changed: 31 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -192,6 +192,21 @@ func registerProjectMappings() {
192192
}, nil
193193
})
194194

195+
// ServiceRestoreResult -> proto ServiceRestoreResult conversion
196+
mapper.MustRegister(func(ctx context.Context, src *ServiceRestoreResult) (*azdext.ServiceRestoreResult, error) {
197+
if src == nil {
198+
return nil, nil
199+
}
200+
201+
var artifacts []*azdext.Artifact
202+
if err := mapper.Convert(src.Artifacts, &artifacts); err != nil {
203+
return nil, err
204+
}
205+
return &azdext.ServiceRestoreResult{
206+
Artifacts: artifacts,
207+
}, nil
208+
})
209+
195210
// ServiceBuildResult -> proto ServiceBuildResult conversion
196211
mapper.MustRegister(func(ctx context.Context, src *ServiceBuildResult) (*azdext.ServiceBuildResult, error) {
197212
if src == nil {
@@ -422,6 +437,22 @@ func registerProjectMappings() {
422437
return result, nil
423438
})
424439

440+
// proto ServiceRestoreResult -> ServiceRestoreResult conversion
441+
mapper.MustRegister(func(ctx context.Context, src *azdext.ServiceRestoreResult) (*ServiceRestoreResult, error) {
442+
if src == nil {
443+
return nil, nil
444+
}
445+
446+
result := &ServiceRestoreResult{}
447+
448+
// Convert artifacts
449+
if err := mapper.Convert(src.Artifacts, &result.Artifacts); err != nil {
450+
return nil, fmt.Errorf("failed to convert artifacts: %w", err)
451+
}
452+
453+
return result, nil
454+
})
455+
425456
// proto ServiceBuildResult -> ServiceBuildResult conversion
426457
mapper.MustRegister(func(ctx context.Context, src *azdext.ServiceBuildResult) (*ServiceBuildResult, error) {
427458
if src == nil {
Lines changed: 113 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,113 @@
1+
// Copyright (c) Microsoft Corporation. All rights reserved.
2+
// Licensed under the MIT License.
3+
4+
package cli_test
5+
6+
import (
7+
"os"
8+
"path/filepath"
9+
"testing"
10+
11+
"github.com/azure/azure-dev/cli/azd/test/azdcli"
12+
"github.com/azure/azure-dev/cli/azd/test/recording"
13+
"github.com/stretchr/testify/require"
14+
)
15+
16+
// Test_CLI_Extension_Capabilities tests the extension framework capabilities using the demo extension.
17+
// This test verifies that:
18+
// 1. The demo extension can be built and installed
19+
// 2. The extension-capabilities sample project can run through the full azd up workflow
20+
// 3. The extension's framework service manager handles restore, build, package operations correctly
21+
func Test_CLI_Extension_Capabilities(t *testing.T) {
22+
// Skip in playback mode: extensions make Azure calls through gRPC callbacks that are difficult to record
23+
// The extension workflow calls back into azd commands which would need complex recording setup
24+
session := recording.Start(t)
25+
if session != nil && session.Playback {
26+
t.Skip("Skipping test in playback mode. This test is live only.")
27+
}
28+
29+
ctx, cancel := newTestContext(t)
30+
defer cancel()
31+
32+
dir := tempDirWithDiagnostics(t)
33+
t.Logf("DIR: %s", dir)
34+
35+
// Generate environment name early (before session starts)
36+
// so we can use it for both extension installation and the recorded part
37+
envName := randomOrStoredEnvName(session)
38+
t.Logf("AZURE_ENV_NAME: %s", envName)
39+
40+
// Step 1: Build and install extensions (not recorded)
41+
// Create a CLI without session for extension operations
42+
cliNoSession := azdcli.NewCLI(t)
43+
cliNoSession.WorkingDirectory = dir
44+
cliNoSession.Env = append(cliNoSession.Env, os.Environ()...)
45+
cliNoSession.Env = append(cliNoSession.Env, "AZURE_LOCATION=eastus2")
46+
47+
t.Log("Installing microsoft.azd.extensions extension")
48+
_, err := cliNoSession.RunCommand(ctx, "ext", "install", "microsoft.azd.extensions", "-s", "azd")
49+
require.NoError(t, err)
50+
51+
// Build the demo extension
52+
t.Log("Building demo extension")
53+
sourcePath := azdcli.GetSourcePath()
54+
demoExtPath := filepath.Join(sourcePath, "extensions", "microsoft.azd.demo")
55+
cliForExtBuild := azdcli.NewCLI(t)
56+
cliForExtBuild.WorkingDirectory = demoExtPath
57+
cliForExtBuild.Env = append(cliForExtBuild.Env, os.Environ()...)
58+
59+
// Add azd binary directory to PATH so 'azd x publish' can find azd
60+
azdDir := filepath.Dir(cliNoSession.AzdPath)
61+
pathEnv := "PATH=" + azdDir + string(os.PathListSeparator) + os.Getenv("PATH")
62+
cliForExtBuild.Env = append(cliForExtBuild.Env, pathEnv)
63+
64+
_, err = cliForExtBuild.RunCommand(ctx, "x", "build")
65+
require.NoError(t, err)
66+
67+
_, err = cliForExtBuild.RunCommand(ctx, "x", "pack")
68+
require.NoError(t, err)
69+
70+
_, err = cliForExtBuild.RunCommand(ctx, "x", "publish")
71+
require.NoError(t, err)
72+
73+
// Install the demo extension from local source
74+
t.Log("Installing demo extension from local source")
75+
_, err = cliNoSession.RunCommand(ctx, "ext", "install", "microsoft.azd.demo", "-s", "local")
76+
require.NoError(t, err)
77+
78+
// Cleanup: Uninstall extensions at the end of the test
79+
defer func() {
80+
t.Log("Uninstalling demo extension")
81+
_, _ = cliNoSession.RunCommand(ctx, "ext", "uninstall", "microsoft.azd.demo")
82+
83+
t.Log("Uninstalling microsoft.azd.extensions extension")
84+
_, _ = cliNoSession.RunCommand(ctx, "ext", "uninstall", "microsoft.azd.extensions")
85+
}()
86+
87+
// Step 2: Create CLI with session for recorded operations
88+
cli := azdcli.NewCLI(t, azdcli.WithSession(session))
89+
cli.WorkingDirectory = dir
90+
cli.Env = append(cli.Env, os.Environ()...)
91+
cli.Env = append(cli.Env, "AZURE_LOCATION=eastus2")
92+
93+
defer cleanupDeployments(ctx, t, cli, session, envName)
94+
95+
// Copy the extension-capabilities sample
96+
err = copySample(dir, "extension-capabilities")
97+
require.NoError(t, err, "failed copying sample")
98+
99+
// Step 3: Initialize the project
100+
_, err = cli.RunCommandWithStdIn(ctx, stdinForInit(envName), "init")
101+
require.NoError(t, err)
102+
103+
// Step 4: Run azd up
104+
// The up command will:
105+
// - Provision infrastructure (main.bicep)
106+
// - Restore dependencies via the demo extension
107+
// - Build the project via the demo extension
108+
// - Package the project via the demo extension (buildpacks)
109+
// - Deploy to Azure
110+
t.Log("Running azd up")
111+
_, err = cli.RunCommandWithStdIn(ctx, stdinForProvision(), "up")
112+
require.NoError(t, err)
113+
}
Lines changed: 36 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,36 @@
1+
version: "1.0"
2+
tool: docker
3+
interactions:
4+
- id: 0
5+
args:
6+
- login
7+
- --username
8+
- 00000000-0000-0000-0000-000000000000
9+
- --password-stdin
10+
- acrcq2iipgkrky3y.azurecr.io
11+
exitCode: 0
12+
stdout: |
13+
Login Succeeded
14+
stderr: ""
15+
- id: 1
16+
args:
17+
- push
18+
- acrcq2iipgkrky3y.azurecr.io/extension-capabilities/demo-azdtest-l8f0aee:azd-deploy-1763590301
19+
exitCode: 0
20+
stdout: |
21+
The push refers to repository [acrcq2iipgkrky3y.azurecr.io/extension-capabilities/demo-azdtest-l8f0aee]
22+
cb63a093e6f7: Preparing
23+
4abab3825028: Preparing
24+
82140d9a70a7: Preparing
25+
f3b40b0cdb1c: Preparing
26+
0b1f26057bd0: Preparing
27+
08000c18d16d: Preparing
28+
08000c18d16d: Waiting
29+
4abab3825028: Pushed
30+
cb63a093e6f7: Pushed
31+
82140d9a70a7: Pushed
32+
f3b40b0cdb1c: Pushed
33+
08000c18d16d: Pushed
34+
0b1f26057bd0: Pushed
35+
azd-deploy-1763590301: digest: sha256:9ee75d8cd3a167ea91c1c0e949d3898720d0e63bd4e580d7c7a7e8969ad03e16 size: 1571
36+
stderr: ""

0 commit comments

Comments
 (0)