diff --git a/CHANGELOG.md b/CHANGELOG.md index c517b49..238d071 100644 --- a/CHANGELOG.md +++ b/CHANGELOG.md @@ -7,6 +7,9 @@ and this project adheres to [Semantic Versioning](https://semver.org/spec/v2.0.0 ## [Unreleased] +### Removed + +- Removed support for Salesforce Functions. ([#83](https://github.com/heroku/buildpacks-python/pull/83)) ## [0.5.0] - 2023-07-24 diff --git a/Cargo.lock b/Cargo.lock index 5786622..460ba66 100644 --- a/Cargo.lock +++ b/Cargo.lock @@ -827,7 +827,6 @@ dependencies = [ "libherokubuildpack", "serde", "tar", - "toml", "ureq", ] diff --git a/Cargo.toml b/Cargo.toml index e73e58a..8a5143d 100644 --- a/Cargo.toml +++ b/Cargo.toml @@ -17,7 +17,6 @@ libcnb = "0.13" libherokubuildpack = { version = "0.13", default-features = false, features = ["log"] } serde = "1" tar = { version = "0.4", default-features = false } -toml = "0.7" ureq = { version = "2", default-features = false, features = ["tls"] } [dev-dependencies] diff --git a/src/errors.rs b/src/errors.rs index efdd9f2..8373ffb 100644 --- a/src/errors.rs +++ b/src/errors.rs @@ -1,10 +1,8 @@ use crate::layers::pip_dependencies::PipDependenciesLayerError; use crate::layers::python::PythonLayerError; use crate::package_manager::DeterminePackageManagerError; -use crate::project_descriptor::ProjectDescriptorError; use crate::python_version::{PythonVersion, PythonVersionError, DEFAULT_PYTHON_VERSION}; use crate::runtime_txt::{ParseRuntimeTxtError, RuntimeTxtError}; -use crate::salesforce_functions::{CheckSalesforceFunctionError, FUNCTION_RUNTIME_PROGRAM_NAME}; use crate::utils::{CommandError, DownloadUnpackArchiveError}; use crate::BuildpackError; use indoc::{formatdoc, indoc}; @@ -42,7 +40,6 @@ pub(crate) fn on_error(error: libcnb::Error) { fn on_buildpack_error(error: BuildpackError) { match error { - BuildpackError::CheckSalesforceFunction(error) => on_check_salesforce_function_error(error), BuildpackError::DetectIo(io_error) => log_io_error( "Unable to complete buildpack detection", "determining if the Python buildpack should be run for this application", @@ -50,30 +47,11 @@ fn on_buildpack_error(error: BuildpackError) { ), BuildpackError::DeterminePackageManager(error) => on_determine_package_manager_error(error), BuildpackError::PipDependenciesLayer(error) => on_pip_dependencies_layer_error(error), - BuildpackError::ProjectDescriptor(error) => on_project_descriptor_error(error), BuildpackError::PythonLayer(error) => on_python_layer_error(error), BuildpackError::PythonVersion(error) => on_python_version_error(error), }; } -fn on_project_descriptor_error(error: ProjectDescriptorError) { - match error { - ProjectDescriptorError::Io(io_error) => log_io_error( - "Unable to read project.toml", - "reading the (optional) project.toml file", - &io_error, - ), - ProjectDescriptorError::Parse(toml_error) => log_error( - "Invalid project.toml", - formatdoc! {" - A parsing/validation error error occurred whilst loading the project.toml file. - - Details: {toml_error} - "}, - ), - }; -} - fn on_determine_package_manager_error(error: DeterminePackageManagerError) { match error { DeterminePackageManagerError::Io(io_error) => log_io_error( @@ -239,42 +217,6 @@ fn on_pip_dependencies_layer_error(error: PipDependenciesLayerError) { }; } -fn on_check_salesforce_function_error(error: CheckSalesforceFunctionError) { - match error { - CheckSalesforceFunctionError::Io(io_error) => log_io_error( - "Unable to run the Salesforce Functions self-check command", - &format!("running the '{FUNCTION_RUNTIME_PROGRAM_NAME} check' command"), - &io_error, - ), - CheckSalesforceFunctionError::NonZeroExitStatus(output) => log_error( - "The Salesforce Functions self-check failed", - formatdoc! {" - The '{FUNCTION_RUNTIME_PROGRAM_NAME} check' command failed ({exit_status}), indicating - there is a problem with the Python Salesforce Function in this project. - - Details: - {stderr} - ", - exit_status = output.status, - stderr = String::from_utf8_lossy(&output.stderr), - }, - ), - CheckSalesforceFunctionError::ProgramNotFound => log_error( - "The Salesforce Functions package is not installed", - formatdoc! {" - The '{FUNCTION_RUNTIME_PROGRAM_NAME}' program that is required for Python Salesforce - Functions could not be found. - - Check that the 'salesforce-functions' Python package is listed as a - dependency in 'requirements.txt'. - - If this project is not intended to be a Salesforce Function, remove the - 'type = \"function\"' declaration from 'project.toml' to skip this check. - "}, - ), - }; -} - fn log_io_error(header: &str, occurred_whilst: &str, io_error: &io::Error) { // We don't suggest opening a support ticket, since a subset of I/O errors can be caused // by issues in the application. In the future, perhaps we should try and split these out? diff --git a/src/main.rs b/src/main.rs index b058417..6de0acf 100644 --- a/src/main.rs +++ b/src/main.rs @@ -9,10 +9,8 @@ mod errors; mod layers; mod package_manager; mod packaging_tool_versions; -mod project_descriptor; mod python_version; mod runtime_txt; -mod salesforce_functions; mod utils; use crate::layers::pip_cache::PipCacheLayer; @@ -20,9 +18,7 @@ use crate::layers::pip_dependencies::{PipDependenciesLayer, PipDependenciesLayer use crate::layers::python::{PythonLayer, PythonLayerError}; use crate::package_manager::{DeterminePackageManagerError, PackageManager}; use crate::packaging_tool_versions::PackagingToolVersions; -use crate::project_descriptor::ProjectDescriptorError; use crate::python_version::PythonVersionError; -use crate::salesforce_functions::CheckSalesforceFunctionError; use libcnb::build::{BuildContext, BuildResult, BuildResultBuilder}; use libcnb::data::layer_name; use libcnb::detect::{DetectContext, DetectResult, DetectResultBuilder}; @@ -55,8 +51,6 @@ impl Buildpack for PythonBuildpack { fn build(&self, context: BuildContext) -> libcnb::Result { // We perform all project analysis up front, so the build can fail early if the config is invalid. // TODO: Add a "Build config" header and list all config in one place? - let is_function = salesforce_functions::is_function_project(&context.app_dir) - .map_err(BuildpackError::ProjectDescriptor)?; let package_manager = package_manager::determine_package_manager(&context.app_dir) .map_err(BuildpackError::DeterminePackageManager)?; @@ -86,7 +80,7 @@ impl Buildpack for PythonBuildpack { // Create the layers for the application dependencies and package manager cache. // In the future support will be added for package managers other than pip. - let dependencies_layer_env = match package_manager { + match package_manager { PackageManager::Pip => { log_header("Installing dependencies using Pip"); let pip_cache_layer = context.handle_layer( @@ -106,20 +100,8 @@ impl Buildpack for PythonBuildpack { pip_layer.env } }; - command_env = dependencies_layer_env.apply(Scope::Build, &command_env); - if is_function { - log_header("Validating Salesforce Function"); - salesforce_functions::check_function(&command_env) - .map_err(BuildpackError::CheckSalesforceFunction)?; - log_info("Function passed validation."); - - BuildResultBuilder::new() - .launch(salesforce_functions::launch_config()) - .build() - } else { - BuildResultBuilder::new().build() - } + BuildResultBuilder::new().build() } fn on_error(&self, error: libcnb::Error) { @@ -129,16 +111,12 @@ impl Buildpack for PythonBuildpack { #[derive(Debug)] pub(crate) enum BuildpackError { - /// Errors running the `sf-functions-python check` command. - CheckSalesforceFunction(CheckSalesforceFunctionError), /// IO errors when performing buildpack detection. DetectIo(io::Error), /// Errors determining which Python package manager to use for a project. DeterminePackageManager(DeterminePackageManagerError), /// Errors installing the project's dependencies into a layer using Pip. PipDependenciesLayer(PipDependenciesLayerError), - /// Errors reading and parsing a `project.toml` file. - ProjectDescriptor(ProjectDescriptorError), /// Errors installing Python and required packaging tools into a layer. PythonLayer(PythonLayerError), /// Errors determining which Python version to use for a project. diff --git a/src/project_descriptor.rs b/src/project_descriptor.rs deleted file mode 100644 index f5d3f1e..0000000 --- a/src/project_descriptor.rs +++ /dev/null @@ -1,279 +0,0 @@ -use crate::utils; -use serde::Deserialize; -use std::io; -use std::path::Path; - -/// Reads the `com.salesforce.type` field from any `project.toml` in the specified directory. -/// -/// It is permitted for the `project.toml` file not to exist, or for there to be no `com.salesforce` -/// table within the TOML document, in which case `Ok(None)` will be returned. -/// -/// However, an error will be returned if any other IO error occurred, the file is not valid TOML, -/// or the TOML document does not adhere to the schema. -pub(crate) fn read_salesforce_project_type( - app_dir: &Path, -) -> Result, ProjectDescriptorError> { - read_project_descriptor(app_dir).map(|descriptor| { - descriptor - .unwrap_or_default() - .com - .unwrap_or_default() - .salesforce - .map(|salesforce| salesforce.project_type) - }) -} - -/// Reads any `project.toml` file in the specified directory, parsing it into a [`ProjectDescriptor`]. -/// -/// It is permitted for the `project.toml` file not to exist, in which case `Ok(None)` will be returned. -/// -/// However, an error will be returned if any other IO error occurred, the file is not valid TOML, -/// or the TOML document does not adhere to the schema. -fn read_project_descriptor( - app_dir: &Path, -) -> Result, ProjectDescriptorError> { - let project_descriptor_path = app_dir.join("project.toml"); - - utils::read_optional_file(&project_descriptor_path) - .map_err(ProjectDescriptorError::Io)? - .map(|contents| parse(&contents).map_err(ProjectDescriptorError::Parse)) - .transpose() -} - -/// Parse the contents of a project descriptor TOML file into a [`ProjectDescriptor`]. -/// -/// An error will be returned if the string is not valid TOML, or the TOML document does not -/// adhere to the schema. -fn parse(contents: &str) -> Result { - toml::from_str::(contents) -} - -/// Represents a Cloud Native Buildpack project descriptor file (`project.toml`). -/// -/// Currently only fields used by the buildpack are enforced, so this represents only a -/// subset of the upstream CNB project descriptor schema. -/// -/// See: -#[derive(Debug, Default, Deserialize, PartialEq)] -struct ProjectDescriptor { - com: Option, -} - -/// Represents the `com` table in the project descriptor. -#[derive(Debug, Default, Deserialize, PartialEq)] -struct ComTable { - salesforce: Option, -} - -/// Represents the `com.salesforce` table in the project descriptor. -/// -/// Currently only fields used by the buildpack are enforced, so this represents only a -/// subset of the Salesforce-specific project descriptor schema. -/// -/// See: -#[derive(Debug, Deserialize, PartialEq)] -struct SalesforceTable { - #[serde(rename = "type")] - project_type: SalesforceProjectType, -} - -/// The type of a Salesforce project. -/// -/// For now `Function` is the only valid type, however others will be added in the future. -/// -/// Unknown project types are intentionally rejected, since we're prioritising the UX for -/// functions projects where the type may have been mis-spelt, over forward-compatibility. -#[derive(Debug, Deserialize, PartialEq)] -pub(crate) enum SalesforceProjectType { - #[serde(rename = "function")] - Function, -} - -/// Errors that can occur when reading and parsing a `project.toml` file. -#[derive(Debug)] -pub(crate) enum ProjectDescriptorError { - Io(io::Error), - Parse(toml::de::Error), -} - -#[cfg(test)] -mod tests { - use super::*; - use libcnb_test::assert_contains; - - #[test] - fn deserialize_empty_descriptor() { - assert_eq!(parse("").unwrap(), ProjectDescriptor { com: None }); - } - - #[test] - fn deserialize_non_salesforce_descriptor() { - let toml_str = r#" - [_] - schema-version = "0.2" - - [io.buildpacks] - builder = "my-builder" - - [com.example] - key = "value" - "#; - - assert_eq!( - parse(toml_str), - Ok(ProjectDescriptor { - com: Some(ComTable { salesforce: None }) - }) - ); - } - - #[test] - fn deserialize_function_descriptor() { - let toml_str = r#" - [_] - schema-version = "0.2" - - [com.salesforce] - schema-version = "0.1" - id = "example" - description = "Example function" - type = "function" - salesforce-api-version = "56.0" - "#; - - assert_eq!( - parse(toml_str), - Ok(ProjectDescriptor { - com: Some(ComTable { - salesforce: Some(SalesforceTable { - project_type: SalesforceProjectType::Function - }) - }) - }) - ); - } - - #[test] - fn deserialize_minimal_function_descriptor() { - let toml_str = r#" - [com.salesforce] - type = "function" - "#; - - assert_eq!( - parse(toml_str), - Ok(ProjectDescriptor { - com: Some(ComTable { - salesforce: Some(SalesforceTable { - project_type: SalesforceProjectType::Function - }) - }) - }) - ); - } - - #[test] - fn reject_salesforce_table_with_no_project_type() { - let toml_str = r#" - [com.salesforce] - schema-version = "0.1" - id = "example" - "#; - - let error = parse(toml_str).unwrap_err(); - assert_contains!(error.to_string(), "missing field `type`"); - } - - #[test] - fn reject_unknown_salesforce_project_type() { - let toml_str = r#" - [com.salesforce] - type = "some_unknown_type" - "#; - - let error = parse(toml_str).unwrap_err(); - assert_contains!( - error.to_string(), - "unknown variant `some_unknown_type`, expected `function`" - ); - } - - #[test] - fn read_project_descriptor_no_project_toml_file() { - let app_dir = Path::new("tests/fixtures/empty"); - - assert_eq!(read_project_descriptor(app_dir).unwrap(), None); - } - - #[test] - fn read_project_descriptor_non_salesforce() { - let app_dir = Path::new("tests/fixtures/project_toml_non_salesforce"); - - assert_eq!( - read_project_descriptor(app_dir).unwrap(), - Some(ProjectDescriptor { - com: Some(ComTable { salesforce: None }) - }) - ); - } - - #[test] - fn read_project_descriptor_function() { - let app_dir = Path::new("tests/fixtures/salesforce_function_template"); - - assert_eq!( - read_project_descriptor(app_dir).unwrap(), - Some(ProjectDescriptor { - com: Some(ComTable { - salesforce: Some(SalesforceTable { - project_type: SalesforceProjectType::Function - }) - }) - }) - ); - } - - #[test] - fn read_project_descriptor_invalid_project_toml_file() { - let app_dir = Path::new("tests/fixtures/project_toml_invalid"); - - assert!(matches!( - read_project_descriptor(app_dir).unwrap_err(), - ProjectDescriptorError::Parse(_) - )); - } - - #[test] - fn get_salesforce_project_type_missing() { - let app_dir = Path::new("tests/fixtures/empty"); - - assert_eq!(read_salesforce_project_type(app_dir).unwrap(), None); - } - - #[test] - fn get_salesforce_project_type_non_salesforce() { - let app_dir = Path::new("tests/fixtures/project_toml_non_salesforce"); - - assert_eq!(read_salesforce_project_type(app_dir).unwrap(), None); - } - - #[test] - fn get_salesforce_project_type_function() { - let app_dir = Path::new("tests/fixtures/salesforce_function_template"); - - assert_eq!( - read_salesforce_project_type(app_dir).unwrap(), - Some(SalesforceProjectType::Function) - ); - } - - #[test] - fn get_salesforce_project_type_invalid_project_toml_file() { - let app_dir = Path::new("tests/fixtures/project_toml_invalid"); - - assert!(matches!( - read_salesforce_project_type(app_dir).unwrap_err(), - ProjectDescriptorError::Parse(_) - )); - } -} diff --git a/src/salesforce_functions.rs b/src/salesforce_functions.rs deleted file mode 100644 index 90b7476..0000000 --- a/src/salesforce_functions.rs +++ /dev/null @@ -1,119 +0,0 @@ -use crate::project_descriptor::{self, ProjectDescriptorError, SalesforceProjectType}; -use libcnb::data::launch::{Launch, LaunchBuilder, ProcessBuilder}; -use libcnb::data::process_type; -use libcnb::Env; -use std::io; -use std::path::Path; -use std::process::{Command, Output}; - -/// The program/script name of the Python Functions runtime's CLI. -pub(crate) const FUNCTION_RUNTIME_PROGRAM_NAME: &str = "sf-functions-python"; - -/// Detect whether the specified project directory is that of a Salesforce Function. -/// -/// Returns `Ok(true)` if the specified project directory contains a `project.toml` file with a -/// `com.salesforce.type` of "function". -/// -/// It is permitted for the `project.toml` file not to exist, or for there to be no `com.salesforce` -/// TOML table within the file, in which case `Ok(false)` will be returned. -/// -/// However, an error will be returned if any other IO error occurred, if the `project.toml` file -/// is not valid TOML, or the TOML document does not adhere to the schema. -pub(crate) fn is_function_project(app_dir: &Path) -> Result { - project_descriptor::read_salesforce_project_type(app_dir) - .map(|project_type| project_type == Some(SalesforceProjectType::Function)) -} - -/// Validate the function using the `sf-functions-python check` command. -pub(crate) fn check_function(command_env: &Env) -> Result<(), CheckSalesforceFunctionError> { - // Not using `utils::run_command` since we want to capture output and only - // display it if the check command fails. - Command::new(FUNCTION_RUNTIME_PROGRAM_NAME) - .args(["check", "."]) - .env_clear() - .envs(command_env) - .output() - .map_err(|io_error| match io_error.kind() { - io::ErrorKind::NotFound => CheckSalesforceFunctionError::ProgramNotFound, - _ => CheckSalesforceFunctionError::Io(io_error), - }) - .and_then(|output| { - if output.status.success() { - Ok(()) - } else { - Err(CheckSalesforceFunctionError::NonZeroExitStatus(output)) - } - }) -} - -/// Generate a `launch.toml` configuration for running Python Salesforce Functions. -/// -/// Runs the `sf-functions-python serve` command with suitable options for production. -pub(crate) fn launch_config() -> Launch { - LaunchBuilder::new() - .process( - // TODO: Stop running via bash once the launcher supports env var interpolation: - // https://github.com/buildpacks/rfcs/issues/258 - ProcessBuilder::new(process_type!("web"), ["bash"]) - .args([ - "-c", - &[ - "exec", - FUNCTION_RUNTIME_PROGRAM_NAME, - "serve", - "--host", - "0.0.0.0", - "--port", - "\"${PORT:-8080}\"", - // TODO: Determine optimal number of workers. - "--workers", - "4", - ".", - ] - .join(" "), - ]) - .default(true) - .build(), - ) - .build() -} - -/// Errors that can occur when running the `sf-functions-python check` command. -#[derive(Debug)] -pub(crate) enum CheckSalesforceFunctionError { - Io(io::Error), - NonZeroExitStatus(Output), - ProgramNotFound, -} - -#[cfg(test)] -mod tests { - use super::*; - - #[test] - fn is_function_project_no_project_toml() { - assert!(!is_function_project(Path::new("tests/fixtures/empty")).unwrap()); - } - - #[test] - fn is_function_project_non_salesforce_project_toml() { - assert!( - !is_function_project(Path::new("tests/fixtures/project_toml_non_salesforce")).unwrap() - ); - } - - #[test] - fn is_function_project_valid_function_project_toml() { - assert!( - is_function_project(Path::new("tests/fixtures/salesforce_function_template")).unwrap() - ); - } - - #[test] - fn is_function_project_invalid_project_toml() { - assert!(matches!( - is_function_project(Path::new("tests/fixtures/project_toml_invalid")).unwrap_err(), - ProjectDescriptorError::Parse(_) - )); - } -} diff --git a/tests/fixtures/project_toml_invalid/project.toml b/tests/fixtures/project_toml_invalid/project.toml deleted file mode 100644 index 7a6399a..0000000 --- a/tests/fixtures/project_toml_invalid/project.toml +++ /dev/null @@ -1,5 +0,0 @@ -[_] -schema-version = "0.2" - -[com.salesforce] -# The required fields here are missing. diff --git a/tests/fixtures/project_toml_invalid/requirements.txt b/tests/fixtures/project_toml_invalid/requirements.txt deleted file mode 100644 index e69de29..0000000 diff --git a/tests/fixtures/project_toml_non_salesforce/project.toml b/tests/fixtures/project_toml_non_salesforce/project.toml deleted file mode 100644 index dd8b5ef..0000000 --- a/tests/fixtures/project_toml_non_salesforce/project.toml +++ /dev/null @@ -1,8 +0,0 @@ -[_] -schema-version = "0.2" - -[io.buildpacks] -builder = "my-builder" - -[com.example] -key = "value" diff --git a/tests/fixtures/salesforce_function_fails_self_check/main.py b/tests/fixtures/salesforce_function_fails_self_check/main.py deleted file mode 100644 index b46ee45..0000000 --- a/tests/fixtures/salesforce_function_fails_self_check/main.py +++ /dev/null @@ -1,5 +0,0 @@ -from salesforce_functions import Context, InvocationEvent - - -def function(_event: InvocationEvent[None], _context: Context) -> None: - return None diff --git a/tests/fixtures/salesforce_function_fails_self_check/project.toml b/tests/fixtures/salesforce_function_fails_self_check/project.toml deleted file mode 100644 index 2a44a3a..0000000 --- a/tests/fixtures/salesforce_function_fails_self_check/project.toml +++ /dev/null @@ -1,3 +0,0 @@ -[com.salesforce] -type = "function" -salesforce-api-version = "invalid" diff --git a/tests/fixtures/salesforce_function_fails_self_check/requirements.txt b/tests/fixtures/salesforce_function_fails_self_check/requirements.txt deleted file mode 100644 index ced5be3..0000000 --- a/tests/fixtures/salesforce_function_fails_self_check/requirements.txt +++ /dev/null @@ -1 +0,0 @@ -salesforce-functions diff --git a/tests/fixtures/salesforce_function_missing_package/main.py b/tests/fixtures/salesforce_function_missing_package/main.py deleted file mode 100644 index 80920de..0000000 --- a/tests/fixtures/salesforce_function_missing_package/main.py +++ /dev/null @@ -1,5 +0,0 @@ -from salesforce_functions import Context, InvocationEvent - - -async def function(_event: InvocationEvent[None], _context: Context) -> None: - return None diff --git a/tests/fixtures/salesforce_function_missing_package/project.toml b/tests/fixtures/salesforce_function_missing_package/project.toml deleted file mode 100644 index ef6d5f8..0000000 --- a/tests/fixtures/salesforce_function_missing_package/project.toml +++ /dev/null @@ -1,2 +0,0 @@ -[com.salesforce] -type = "function" diff --git a/tests/fixtures/salesforce_function_missing_package/requirements.txt b/tests/fixtures/salesforce_function_missing_package/requirements.txt deleted file mode 100644 index fbb9d22..0000000 --- a/tests/fixtures/salesforce_function_missing_package/requirements.txt +++ /dev/null @@ -1 +0,0 @@ -# The salesforce-functions package is missing from here. diff --git a/tests/fixtures/salesforce_function_template/README.md b/tests/fixtures/salesforce_function_template/README.md deleted file mode 100644 index 4bcafa9..0000000 --- a/tests/fixtures/salesforce_function_template/README.md +++ /dev/null @@ -1,3 +0,0 @@ -# Pythonexample Function - - diff --git a/tests/fixtures/salesforce_function_template/main.py b/tests/fixtures/salesforce_function_template/main.py deleted file mode 100644 index 4c05d20..0000000 --- a/tests/fixtures/salesforce_function_template/main.py +++ /dev/null @@ -1,20 +0,0 @@ -from typing import Any - -from salesforce_functions import Context, InvocationEvent, get_logger - -# The type of the data payload sent with the invocation event. -# Change this to a more specific type matching the expected payload for -# improved IDE auto-completion and linting coverage. For example: -# `EventPayloadType = dict[str, Any]` -EventPayloadType = Any - -logger = get_logger() - - -async def function(event: InvocationEvent[EventPayloadType], context: Context): - """Describe the function here.""" - - result = await context.org.data_api.query("SELECT Id, Name FROM Account") - logger.info(f"Function successfully queried {result.total_size} account records!") - - return result.records diff --git a/tests/fixtures/salesforce_function_template/payload.json b/tests/fixtures/salesforce_function_template/payload.json deleted file mode 100644 index 0967ef4..0000000 --- a/tests/fixtures/salesforce_function_template/payload.json +++ /dev/null @@ -1 +0,0 @@ -{} diff --git a/tests/fixtures/salesforce_function_template/project.toml b/tests/fixtures/salesforce_function_template/project.toml deleted file mode 100644 index ac505f2..0000000 --- a/tests/fixtures/salesforce_function_template/project.toml +++ /dev/null @@ -1,9 +0,0 @@ -[_] -schema-version = "0.2" - -[com.salesforce] -schema-version = "0.1" -id = "pythonexample" -description = "A Salesforce Function" -type = "function" -salesforce-api-version = "56.0" diff --git a/tests/fixtures/salesforce_function_template/requirements.txt b/tests/fixtures/salesforce_function_template/requirements.txt deleted file mode 100644 index ced5be3..0000000 --- a/tests/fixtures/salesforce_function_template/requirements.txt +++ /dev/null @@ -1 +0,0 @@ -salesforce-functions diff --git a/tests/integration/mod.rs b/tests/integration/mod.rs index 0d295ef..97f548c 100644 --- a/tests/integration/mod.rs +++ b/tests/integration/mod.rs @@ -7,7 +7,6 @@ mod detect; mod package_manager; mod pip; mod python_version; -mod salesforce_functions; const LATEST_PYTHON_3_7: &str = "3.7.17"; const LATEST_PYTHON_3_8: &str = "3.8.17"; diff --git a/tests/integration/salesforce_functions.rs b/tests/integration/salesforce_functions.rs deleted file mode 100644 index c6d4ed8..0000000 --- a/tests/integration/salesforce_functions.rs +++ /dev/null @@ -1,137 +0,0 @@ -use crate::integration_tests::builder; -use indoc::indoc; -use libcnb_test::{ - assert_contains, assert_empty, BuildConfig, ContainerConfig, PackResult, TestRunner, -}; -use std::thread; -use std::time::Duration; - -const TEST_PORT: u16 = 12345; - -#[test] -#[ignore = "integration test"] -fn salesforce_function_template() { - TestRunner::default().build( - BuildConfig::new(builder(), "tests/fixtures/salesforce_function_template"), - |context| { - assert_empty!(context.pack_stderr); - assert_contains!( - context.pack_stdout, - indoc! {" - [Validating Salesforce Function] - Function passed validation. - ===> EXPORTING - "} - ); - assert_contains!(context.pack_stdout, "Setting default process type 'web'"); - - // Test that the `sf-functions-python` web process the buildpack configures works correctly. - context.start_container( - ContainerConfig::new() - .env("PORT", TEST_PORT.to_string()) - .expose_port(TEST_PORT), - |container| { - let address_on_host = container.address_for_port(TEST_PORT).unwrap(); - let url = format!("http://{}:{}", address_on_host.ip(), address_on_host.port()); - - // Retries needed since the server takes a moment to start up. - let mut attempts_remaining = 5; - let response = loop { - let response = ureq::post(&url).set("x-health-check", "true").call(); - if response.is_ok() || attempts_remaining == 0 { - break response; - } - attempts_remaining -= 1; - thread::sleep(Duration::from_secs(1)); - }; - - let server_log_output = container.logs_now(); - assert_contains!( - server_log_output.stderr, - &format!("Uvicorn running on http://0.0.0.0:{TEST_PORT}") - ); - - let body = response.unwrap().into_string().unwrap(); - assert_eq!(body, r#""OK""#); - }, - ); - }, - ); -} - -#[test] -#[ignore = "integration test"] -fn salesforce_function_missing_package() { - TestRunner::default().build( - BuildConfig::new( - builder(), - "tests/fixtures/salesforce_function_missing_package", - ) - .expected_pack_result(PackResult::Failure), - |context| { - assert_contains!( - context.pack_stderr, - indoc! {r#" - [Error: The Salesforce Functions package is not installed] - The 'sf-functions-python' program that is required for Python Salesforce - Functions could not be found. - - Check that the 'salesforce-functions' Python package is listed as a - dependency in 'requirements.txt'. - - If this project is not intended to be a Salesforce Function, remove the - 'type = "function"' declaration from 'project.toml' to skip this check. - "#} - ); - }, - ); -} - -#[test] -#[ignore = "integration test"] -fn salesforce_function_fails_self_check() { - TestRunner::default().build( - BuildConfig::new( - builder(), - "tests/fixtures/salesforce_function_fails_self_check", - ) - .expected_pack_result(PackResult::Failure), - |context| { - assert_contains!( - context.pack_stderr, - indoc! {" - [Error: The Salesforce Functions self-check failed] - The 'sf-functions-python check' command failed (exit status: 1), indicating - there is a problem with the Python Salesforce Function in this project. - - Details: - Function failed validation: 'invalid' isn't a valid Salesforce REST API version." - } - ); - }, - ); -} - -#[test] -#[ignore = "integration test"] -fn project_toml_invalid() { - TestRunner::default().build( - BuildConfig::new(builder(), "tests/fixtures/project_toml_invalid") - .expected_pack_result(PackResult::Failure), - |context| { - assert_contains!( - context.pack_stderr, - indoc! {r#" - [Error: Invalid project.toml] - A parsing/validation error error occurred whilst loading the project.toml file. - - Details: TOML parse error at line 4, column 1 - | - 4 | [com.salesforce] - | ^^^^^^^^^^^^^^^^ - missing field `type` - "#} - ); - }, - ); -}