Repository: caddyserver/caddy (language: go)

Issue:
`caddytest.Tester` should ensure that `AppDataDir` exists
Caddy (including Caddies run as `caddytest.Tester`) will create `instance.uuid` if it doesn't already exist. However, this will fail if `caddy.AppDataDir()` doesn't already exist, which appears to be the case when `caddytest.Tester` is used on Linux (though not on Windows or macOS, which I don't understand).

This makes it difficult to use `caddytest.Tester` to test modules that need `caddy.InstanceID()` to work. See for example my struggles in https://github.com/mholt/caddy-ratelimit/pull/34, where I resorted to doing `os.MkdirAll(caddy.AppDataDir())`, which works well enough in CI, but doesn't feel like a great solution.

It'd be nice if `caddytest.Tester` could consistently guarantee that `AppDataDir` will exist, or perhaps it could avoid writing the instance ID to disk altogether since a `caddytest.Tester` instance is not likely to need persistence across restarts.


Discussion / hints:
Good point. Redoing our caddytest package was on my list for 2.8 (then the baby came early, then life got busy, and I got behind on my backlog, so testing has been deferred another cycle again, sorry).

But in the meantime we could probably work in a fix for this before then.
I can take a look at this!
Sounds good, let us know if you have questions @armadi1809  
@mholt I guess this can be resolved in two ways: 

1- Inside  the `InstanceID ` function, check if the path returned by `AppDataDir()` exists and create it if it does not. 
2- get rid the part of the `InstanceID`  function that writes the UUID to disk. 

Which one is preferred? After a quick search through the code base, it doesn't look like the UUID file is being used somewhere else other than where it's being created (i.e. inside the `InstanceID` function)  but I might be wrong. 
@armadi1809 I think 1 is best. A call to `MkdirAll()` should do the trick.

@tgeoghegan AppDataDir() honors XDG env vars, so maybe tests could set XDG_DATA_HOME to a temporary directory.

Fix patch:
diff --git a/caddy.go b/caddy.go
index 8e7dce50764..4a7bd8b6d05 100644
--- a/caddy.go
+++ b/caddy.go
@@ -825,13 +825,18 @@ func ParseDuration(s string) (time.Duration, error) {
 // regardless of storage configuration, since each instance is intended to
 // have its own unique ID.
 func InstanceID() (uuid.UUID, error) {
-	uuidFilePath := filepath.Join(AppDataDir(), "instance.uuid")
+	appDataDir := AppDataDir()
+	uuidFilePath := filepath.Join(appDataDir, "instance.uuid")
 	uuidFileBytes, err := os.ReadFile(uuidFilePath)
 	if os.IsNotExist(err) {
 		uuid, err := uuid.NewRandom()
 		if err != nil {
 			return uuid, err
 		}
+		err = os.MkdirAll(appDataDir, 0o600)
+		if err != nil {
+			return uuid, err
+		}
 		err = os.WriteFile(uuidFilePath, []byte(uuid.String()), 0o600)
 		return uuid, err
 	} else if err != nil {


Test patch: