Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

feat: jaas integration tests #561

Merged
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension


Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
90 changes: 90 additions & 0 deletions .github/workflows/test_integration_jaas.yaml
Original file line number Diff line number Diff line change
@@ -0,0 +1,90 @@
# A similar set of tests to test_integration but against a JAAS controller
name: Integration tests with JAAS

# This GitHub action runs your tests for each pull request.
on:
pull_request:
paths-ignore:
- "README.md"
- "project-docs/**"
- ".github/ISSUE_TEMPLATE/**"
- ".github/PULL_REQUEST_TEMPLATE.md"
push:
branches:
- "main"
paths-ignore:
- "README.md"
- "project-docs/**"
- ".github/ISSUE_TEMPLATE/**"
- ".github/PULL_REQUEST_TEMPLATE.md"
workflow_dispatch:

# Testing needs read permission and access to Github's container registry to pull JIMM.
permissions:
contents: read
packages: read

jobs:
# Ensure project builds before running test
build:
name: Build
runs-on: ubuntu-latest
timeout-minutes: 5
steps:
- uses: actions/checkout@v4
- uses: actions/setup-go@v5
with:
go-version-file: "go.mod"
cache: true
- run: go build -v .

test:
name: Integration
needs: build
runs-on: ubuntu-latest
strategy:
fail-fast: false
timeout-minutes: 60
steps:
- uses: actions/checkout@v4
- uses: actions/setup-go@v5
with:
go-version-file: "go.mod"
cache: true
- uses: hashicorp/setup-terraform@v3
with:
terraform_version: "1.9.*"
terraform_wrapper: false
kian99 marked this conversation as resolved.
Show resolved Hide resolved
# Starting JAAS will start the JIMM controller and dependencies and create a Juju controller on LXD and connect it to JIMM.
- name: Setup JAAS
uses: canonical/jimm/.github/actions/test-server@v3
id: jaas
with:
jimm-version: v3.1.8
juju-channel: 3/stable
ghcr-pat: ${{ secrets.GITHUB_TOKEN }}
- name: Create additional networks when testing with LXD
run: |
sudo lxc network create management-br ipv4.address=10.150.40.1/24 ipv4.nat=true ipv6.address=none ipv6.nat=false
sudo lxc network create public-br ipv4.address=10.170.80.1/24 ipv4.nat=true ipv6.address=none ipv6.nat=false
- name: "Set environment to configure provider"
# language=bash
run: |
CONTROLLER=$(juju whoami --format yaml | yq .controller)

echo "IS_JAAS=true" >> $GITHUB_ENV
echo "JUJU_AGENT_VERSION=$(juju show-controller | yq .$CONTROLLER.details.agent-version |tr -d '"')" >> $GITHUB_ENV
echo "JUJU_CONTROLLER_ADDRESSES=$(juju show-controller | yq .$CONTROLLER.details.api-endpoints | yq -r '. | join(",")')" >> $GITHUB_ENV
echo "JUJU_CLIENT_ID=${{ steps.jaas.outputs.client-id }}" >> $GITHUB_ENV
echo "JUJU_CLIENT_SECRET=${{ steps.jaas.outputs.client-secret }}" >> $GITHUB_ENV
echo "JUJU_CA_CERT<<EOF" >> $GITHUB_ENV
echo "${{ steps.jaas.outputs.ca-cert }}" >> $GITHUB_ENV
echo "EOF" >> $GITHUB_ENV
echo "TEST_MANAGEMENT_BR=10.150.40.0/24" >> $GITHUB_ENV
echo "TEST_PUBLIC_BR=10.170.80.0/24" >> $GITHUB_ENV
- run: go mod download
- env:
TF_ACC: "1"
TEST_CLOUD: "lxd"
run: go test -parallel 1 -timeout 40m -v -cover ./internal/provider/
timeout-minutes: 40
55 changes: 49 additions & 6 deletions internal/provider/provider_test.go
Original file line number Diff line number Diff line change
Expand Up @@ -21,7 +21,10 @@ import (
"github.com/juju/terraform-provider-juju/internal/juju"
)

const TestProviderStableVersion = "0.12.0"
const (
TestProviderStableVersion = "0.12.0"
isJaasEnvKey = "IS_JAAS"
)

// providerFactories are used to instantiate the Framework provider during
// acceptance testing.
Expand All @@ -43,6 +46,24 @@ func init() {
}
}

// SkipJAAS should be called at the top of any tests that are not appropriate to
// run against JAAS. These include things like Juju access related tests where a
// JAAS specific resource is available.
func SkipJAAS(t *testing.T) {
if _, ok := os.LookupEnv("IS_JAAS"); ok {
t.Skip("Skipping test when running against JAAS")
}
}

// OnlyTestAgainstJAAS should be called at the top of any tests that are not
// appropriate to run against a Juju controller. This includes tests for all JAAS
// specific resources where only JAAS implements the necessary API methods.
func OnlyTestAgainstJAAS(t *testing.T) {
if _, ok := os.LookupEnv("IS_JAAS"); !ok {
t.Skip("Skipping JAAS specific test against Juju")
}
}

func TestProviderConfigure(t *testing.T) {
testAccPreCheck(t)
jujuProvider := NewJujuProvider("dev")
Expand All @@ -51,6 +72,7 @@ func TestProviderConfigure(t *testing.T) {
}

func TestProviderConfigureUsernameFromEnv(t *testing.T) {
SkipJAAS(t)
testAccPreCheck(t)
jujuProvider := NewJujuProvider("dev")
userNameValue := "the-username"
Expand All @@ -65,6 +87,7 @@ func TestProviderConfigureUsernameFromEnv(t *testing.T) {
}

func TestProviderConfigurePasswordFromEnv(t *testing.T) {
SkipJAAS(t)
testAccPreCheck(t)
jujuProvider := NewJujuProvider("dev")
passwordValue := "the-password"
Expand All @@ -78,6 +101,7 @@ func TestProviderConfigurePasswordFromEnv(t *testing.T) {
}

func TestProviderConfigureClientIDAndSecretFromEnv(t *testing.T) {
SkipJAAS(t)
testAccPreCheck(t)
jujuProvider := NewJujuProvider("dev")
emptyValue := ""
Expand Down Expand Up @@ -118,6 +142,7 @@ const (

// TODO: find an alternative way of running test on Mac
func TestProviderConfigurex509FromEnv(t *testing.T) {
SkipJAAS(t)
if runtime.GOOS == "darwin" {
//Due to a bug in Go this test does not work on darwin OS
//https://github.com/golang/go/issues/52010
Expand All @@ -135,6 +160,7 @@ func TestProviderConfigurex509FromEnv(t *testing.T) {
}

func TestProviderConfigurex509InvalidFromEnv(t *testing.T) {
SkipJAAS(t)
jujuProvider := NewJujuProvider("dev")
//Set the CA to the invalid one above
//Juju will ignore the system trust store if we set the CA property
Expand All @@ -153,6 +179,28 @@ func testAccPreCheck(t *testing.T) {
if TestClient != nil {
return
}
if val, ok := os.LookupEnv(isJaasEnvKey); ok && val == "true" {
validateJAASTestConfig(t)
} else {
validateJujuTestConfig(t)
}
confResp := configureProvider(t, Provider)
assert.Equal(t, confResp.Diagnostics.HasError(), false, confResp.Diagnostics.Errors())
testClient, ok := confResp.ResourceData.(*juju.Client)
assert.Truef(t, ok, "ResourceData, not of type juju client")
TestClient = testClient
}

func validateJAASTestConfig(t *testing.T) {
if v := os.Getenv(JujuClientIDEnvKey); v == "" {
t.Fatalf("%s must be set for acceptance tests", JujuClientIDEnvKey)
}
if v := os.Getenv(JujuClientSecretEnvKey); v == "" {
t.Fatalf("%s must be set for acceptance tests", JujuClientSecretEnvKey)
}
}

func validateJujuTestConfig(t *testing.T) {
if v := os.Getenv(JujuUsernameEnvKey); v == "" {
t.Fatalf("%s must be set for acceptance tests", JujuUsernameEnvKey)
}
Expand All @@ -171,11 +219,6 @@ func testAccPreCheck(t *testing.T) {
t.Fatalf("%s must be set for acceptance tests", JujuCACertEnvKey)
}
}
confResp := configureProvider(t, Provider)
assert.Equal(t, confResp.Diagnostics.HasError(), false)
testClient, ok := confResp.ResourceData.(*juju.Client)
assert.Truef(t, ok, "ResourceData, not of type juju client")
TestClient = testClient
}

func configureProvider(t *testing.T, p provider.Provider) provider.ConfigureResponse {
Expand Down
2 changes: 2 additions & 0 deletions internal/provider/resource_access_model_test.go
Original file line number Diff line number Diff line change
Expand Up @@ -13,6 +13,7 @@ import (
)

func TestAcc_ResourceAccessModel(t *testing.T) {
SkipJAAS(t)
userName := acctest.RandomWithPrefix("tfuser")
userPassword := acctest.RandomWithPrefix("tf-test-user")
userName2 := acctest.RandomWithPrefix("tfuser")
Expand Down Expand Up @@ -67,6 +68,7 @@ func TestAcc_ResourceAccessModel(t *testing.T) {
}

func TestAcc_ResourceAccessModel_UpgradeProvider(t *testing.T) {
SkipJAAS(t)
if testingCloud != LXDCloudTesting {
t.Skip(t.Name() + " only runs with LXD")
}
Expand Down
21 changes: 16 additions & 5 deletions internal/provider/resource_offer_test.go
Original file line number Diff line number Diff line change
Expand Up @@ -5,6 +5,7 @@ package provider

import (
"fmt"
"os"
"testing"

"github.com/hashicorp/terraform-plugin-testing/helper/acctest"
Expand All @@ -27,8 +28,8 @@ func TestAcc_ResourceOffer(t *testing.T) {
Config: testAccResourceOffer(modelName, "base = \"[email protected]\""),
Check: resource.ComposeTestCheckFunc(
resource.TestCheckResourceAttr("juju_offer.this", "model", modelName),
resource.TestCheckResourceAttr("juju_offer.this", "url", fmt.Sprintf("%v/%v.%v", "admin", modelName, "this")),
resource.TestCheckResourceAttr("juju_offer.this", "id", fmt.Sprintf("%v/%v.%v", "admin", modelName, "this")),
resource.TestCheckResourceAttr("juju_offer.this", "url", fmt.Sprintf("%v/%v.%v", expectedOfferUser(), modelName, "this")),
resource.TestCheckResourceAttr("juju_offer.this", "id", fmt.Sprintf("%v/%v.%v", expectedOfferUser(), modelName, "this")),
),
},
{
Expand All @@ -40,7 +41,7 @@ func TestAcc_ResourceOffer(t *testing.T) {
map[string]string{"name": "apptwo", "endpoint": "db", "offer_url": ""}),

resource.TestCheckTypeSetElemNestedAttrs("juju_integration.int", "application.*",
map[string]string{"name": "", "endpoint": "", "offer_url": fmt.Sprintf("%v/%v.%v", "admin",
map[string]string{"name": "", "endpoint": "", "offer_url": fmt.Sprintf("%v/%v.%v", expectedOfferUser(),
modelName2, "appone")}),
),
},
Expand Down Expand Up @@ -124,8 +125,8 @@ func TestAcc_ResourceOffer_UpgradeProvider(t *testing.T) {
Config: testAccResourceOffer(modelName, "series = \"focal\""),
Check: resource.ComposeTestCheckFunc(
resource.TestCheckResourceAttr("juju_offer.this", "model", modelName),
resource.TestCheckResourceAttr("juju_offer.this", "url", fmt.Sprintf("%v/%v.%v", "admin", modelName, "this")),
resource.TestCheckResourceAttr("juju_offer.this", "id", fmt.Sprintf("%v/%v.%v", "admin", modelName, "this")),
resource.TestCheckResourceAttr("juju_offer.this", "url", fmt.Sprintf("%v/%v.%v", expectedOfferUser(), modelName, "this")),
resource.TestCheckResourceAttr("juju_offer.this", "id", fmt.Sprintf("%v/%v.%v", expectedOfferUser(), modelName, "this")),
),
},
{
Expand Down Expand Up @@ -161,3 +162,13 @@ resource "juju_offer" "this" {
}
`, modelName, os)
}

func expectedOfferUser() string {
// Only 1 field is expected to be populated.
username := os.Getenv(JujuUsernameEnvKey)
clientId := os.Getenv(JujuClientIDEnvKey)
if clientId != "" {
clientId = clientId + "@serviceaccount"
}
return username + clientId
}
2 changes: 2 additions & 0 deletions internal/provider/resource_user_test.go
Original file line number Diff line number Diff line change
Expand Up @@ -12,6 +12,7 @@ import (
)

func TestAcc_ResourceUser(t *testing.T) {
SkipJAAS(t)
userName := acctest.RandomWithPrefix("tfuser")
userPassword := acctest.RandomWithPrefix("tf-test-user")

Expand Down Expand Up @@ -49,6 +50,7 @@ resource "juju_user" "user" {
}

func TestAcc_ResourceUser_UpgradeProvider(t *testing.T) {
SkipJAAS(t)
userName := acctest.RandomWithPrefix("tfuser")
userPassword := acctest.RandomWithPrefix("tf-test-user")

Expand Down