Imported from juju/juju (
AGENTS.md). Install upstream withnpx skills add juju/juju. Copyright stays with the author.
Juju Agent Rules Index
Apply both files below for any code change:
If guidance conflicts, architectural rules take precedence.
Documentation
- Documentation agent files — Documentation-specific agent guidance.
Build
make install— Full build including schema regeneration.make go-build— Build without schema rebuild.make juju— Build the CLI client only.make jujuagentd— Build the machine agent binary.
Unit Test Conventions
- Always use
tcfor writing unit tests. - Assertions:
- Use
c.Assert(err, tc.ErrorIsNil)for error checks. - Prefer
c.Checkfor value assertions. - Use
c.Assertfor value assertions only when needed to guard subsequent assertions (e.g. prevent nil dereference). - The use of
tc.Must(e.g.tc.Must(c, NewUUID)) should be limited to simple test setup.
- Use
- Checkers:
- Checkers are passed to
c.Assertandc.Checkas the second argument. - Examples of checkers arr
tc.IsTrue,tc.IsFalse,tc.Equalsandtc.DeepEquals. - Use
c.Assert(err, tc.ErrorIs, MySentinalErr)instead ofc.Assert(errors.Is(err, MySentinalErr), tc.Equals, true). - Use
c.Check(booleanExpr, tc.IsTrue)instead ofc.Check(booleanExpr, tc.Equals, true). - There are more Checkers, look for the most appropriate checker.
- Checkers are passed to
- For
selectcases, use test context (c.Context) instead of timeouts. - If a test event must occur, block on it and rely on the native test timeout instead of adding an explicit timeout branch.
Running Tests
Tests must be run with the -race flag for code with mutexes or goroutines.
For code with goroutines, tombs or catacombs, stress must be used to ensure
robustness.
go test ./path/to/package— Run package tests.go test -run 'TestName' ./path/to/package— Run specific test.make pre-check— Static analysis (golangci-lint). Run before submitting.- For
internal/provider/kubernetesunit tests, preferkubernetes.Interfacewithk8s.io/client-go/kubernetes/fake.NewClientsetand reactors over ad hoc function injection when exercising Kubernetes API interactions.
Code Formatting
After editing any Go file, MUST run gci to fix import ordering before
committing. The project uses three import stanzas: stdlib, external, then
github.com/juju/juju — each separated by a blank line.
gci write --section standard --section default --section "Prefix(github.com/juju/juju)" <file>
Run on every .go file touched in the change, excluding generated files
(mocks, *_mock_test.go, etc.). Failing to do so will cause the gci
linter to fail in CI.
Running stress Tests
Compile the go package into a binary and run the test through stress.
A timeout must wrap the stress command to ensure that stress halts in a good
timeframe.
go test ./path/to/package -c -racetimeout 31 stress -timeout 30s ./package.test
Integration Tests (bash-based)
- Located in
tests/suites/*/task.sh. - Run via:
cd tests && ./main.sh <suite>or./main.sh <suite> <test_name>. - Framework includes:
tests/includes/juju.sh(bootstrap, ensure, destroy),tests/includes/wait-for.sh(polling),tests/includes/check.sh(assertions).
General Code Structure Guidelines
- Place methods and functions below others that call them.
- Limit comment line lengths to 80 characters.
- When wrapping errors across layers, add identifying context such as
entity UUIDs once at the highest useful layer. Keep state-layer
Errorfmessages generic to avoid repeated identifiers in the final error chain.