{
  "$comment": "https://github.com/GoogleContainerTools/container-structure-test",
  "$id": "https://json.schemastore.org/container-structure-test.json",
  "$schema": "http://json-schema.org/draft-07/schema#",
  "additionalProperties": false,
  "definitions": {
    "envVar": {
      "$id": "#/definitions/envVar",
      "type": "object",
      "additionalProperties": false,
      "required": ["key", "value"],
      "properties": {
        "key": {
          "type": "string",
          "description": "The name of the environment variables"
        },
        "value": {
          "type": "string",
          "description": "The value of the environment variable"
        }
      }
    },
    "label": {
      "$id": "#/definitions/label",
      "type": "object",
      "additionalProperties": false,
      "required": ["key", "value"],
      "properties": {
        "key": {
          "type": "string",
          "description": "The name of the label"
        },
        "value": {
          "type": "string",
          "description": "The value of the label"
        },
        "isRegex": {
          "type": "boolean",
          "description": "Interpreted the value as regex"
        }
      }
    }
  },
  "description": "The Container Structure Tests provide a powerful framework to validate the structure of a container image. These tests can be used to check the output of commands in an image, as well as verify metadata and contents of the filesystem",
  "properties": {
    "schemaVersion": {
      "type": "string",
      "description": "The schema version of Structure Tests.",
      "default": "2.0.0"
    },
    "commandTests": {
      "type": "array",
      "description": "A list of command tests",
      "items": {
        "type": "object",
        "required": ["name", "command"],
        "properties": {
          "name": {
            "type": "string",
            "description": "The name of the test"
          },
          "setup": {
            "type": "array",
            "description": "A list of commands (each with optional flags) to run before the actual command under test.",
            "items": {
              "type": "array",
              "items": {
                "type": "string"
              }
            }
          },
          "teardown": {
            "type": "array",
            "description": "A list of commands (each with optional flags) to run after the actual command under test.",
            "items": {
              "type": "array",
              "items": {
                "type": "string"
              }
            }
          },
          "envVars": {
            "type": "array",
            "items": {
              "$ref": "#/definitions/envVar"
            }
          },
          "command": {
            "type": "string",
            "description": "The command to run in the test."
          },
          "args": {
            "type": "array",
            "description": "The arguments to pass to the command.",
            "items": {
              "type": "string"
            }
          },
          "expectedOutput": {
            "type": "array",
            "description": "List of regexes that should match the stdout from running the command.",
            "minItems": 1,
            "items": {
              "type": "string"
            }
          },
          "excludedOutput": {
            "type": "array",
            "description": "List of regexes that should not match the stdout from running the command..",
            "minItems": 1,
            "items": {
              "type": "string"
            }
          },
          "expectedError": {
            "type": "array",
            "description": "List of regexes that should match the stderr from running the command.",
            "minItems": 1,
            "items": {
              "type": "string"
            }
          },
          "excludedError": {
            "type": "array",
            "description": "List of regexes that should not match the stderr from running the command.",
            "minItems": 1,
            "items": {
              "type": "string"
            }
          },
          "exitCode": {
            "type": "integer",
            "description": "Exit code that the command should exit with."
          }
        }
      }
    },
    "fileExistenceTests": {
      "type": "array",
      "description": "File existence tests check to make sure a specific file (or directory) exist within the file system of the image. No contents of the files or directories are checked. These tests can also be used to ensure a file or directory is not present in the file system.",
      "items": {
        "type": "object",
        "required": ["name", "path", "shouldExist"],
        "properties": {
          "name": {
            "type": "string",
            "description": "The name of the test"
          },
          "path": {
            "type": "string",
            "description": "Path to the file or directory under test",
            "default": "/"
          },
          "shouldExist": {
            "type": "boolean",
            "description": "Whether or not the specified file or directory should exist in the file system",
            "default": true
          },
          "permissions": {
            "type": "string",
            "description": "The expected Unix permission string (e.g. drwxrwxrwx) of the files or directory."
          },
          "uid": {
            "type": "number",
            "description": "The expected Unix user ID of the owner of the file or directory."
          },
          "gid": {
            "type": "number",
            "description": "The expected Unix group ID of the owner of the file or directory."
          },
          "isExecutableBy": {
            "type": "string",
            "description": "Checks if file is executable by a given user. ",
            "enum": ["owner", "group", "any", "other"]
          }
        }
      }
    },
    "fileContentTests": {
      "description": "File content tests open a file on the file system and check its contents. These tests assume the specified file is a file, and that it exists",
      "type": "array",
      "items": {
        "type": "object",
        "required": ["name", "path"],
        "properties": {
          "name": {
            "type": "string",
            "description": "The name of the test"
          },
          "path": {
            "type": "string",
            "description": "Path to the file under test"
          },
          "expectedContents": {
            "type": "array",
            "description": "List of regexes that should match the contents of the file",
            "minItems": 1,
            "items": {
              "type": "string"
            }
          },
          "excludedContents": {
            "type": "array",
            "description": "List of regexes that should not match the contents of the file",
            "minItems": 1,
            "items": {
              "type": "string"
            }
          }
        }
      }
    },
    "licenseTests": {
      "description": "License tests check a list of copyright files and makes sure all licenses are allowed at Google. By default it will look at where Debian lists all copyright files, but can also look at an arbitrary list of files.",
      "type": "array",
      "items": {
        "type": "object",
        "required": ["debian"],
        "properties": {
          "debian": {
            "type": "boolean",
            "default": true,
            "description": "if the image is based on Debian, check where Debian lists all licenses."
          },
          "files": {
            "type": "array",
            "description": "A list of other files to check.",
            "minItems": 1,
            "items": {
              "type": "string"
            }
          }
        }
      }
    },
    "metadataTest": {
      "type": "object",
      "properties": {
        "env": {
          "type": "array",
          "description": "A list of environment variable key/value pairs that should be set in the container.",
          "minItems": 1,
          "items": {
            "$ref": "#/definitions/envVar"
          }
        },
        "labels": {
          "type": "array",
          "description": "A list of image labels key/value pairs that should be set on the container.",
          "minItems": 1,
          "items": {
            "$ref": "#/definitions/label"
          }
        },
        "entrypoint": {
          "type": "array",
          "description": "The entrypoint of the container",
          "minItems": 1,
          "items": {
            "type": "string"
          }
        },
        "cmd": {
          "type": "array",
          "description": "The CMD specified in the container",
          "minItems": 1,
          "items": {
            "type": "string"
          }
        },
        "exposedPorts": {
          "type": "array",
          "description": "The ports exposed in the container.",
          "minItems": 1,
          "items": {
            "type": "string"
          }
        },
        "unexposedPorts": {
          "type": "array",
          "description": "The ports NOT exposed in the container.",
          "minItems": 1,
          "items": {
            "type": "string"
          }
        },
        "volumes": {
          "type": "array",
          "description": "The volumes exposed in the container.",
          "minItems": 1,
          "items": {
            "type": "string"
          }
        },
        "unmountedVolumes": {
          "type": "array",
          "description": "The volumes NOT exposed in the container",
          "minItems": 1,
          "items": {
            "type": "string"
          }
        },
        "workdir": {
          "type": "string",
          "description": "The default working directory of the container."
        }
      }
    },
    "globalEnvVars": {
      "type": "array",
      "description": "A list of environment variables can optionally be specified as part of the test setup. ",
      "minItems": 1,
      "items": {
        "$ref": "#/definitions/envVar"
      }
    }
  },
  "required": ["schemaVersion"],
  "title": "Container Structure Tests",
  "type": "object"
}
