diff --git a/Makefile.am b/Makefile.am index 270a7ffe..a3500a6d 100644 --- a/Makefile.am +++ b/Makefile.am @@ -213,6 +213,7 @@ BATS = \ test/functional/bundleremove/remove-parse-args.bats \ test/functional/bundleremove/remove-with-dependency.bats \ test/functional/checkupdate/chk-update-client-certificate.bats \ + test/functional/checkupdate/chk-update-format-bump.bats \ test/functional/checkupdate/chk-update-json.bats \ test/functional/checkupdate/chk-update-new-version.bats \ test/functional/checkupdate/chk-update-no-server-content.bats \ diff --git a/src/check_update.c b/src/check_update.c index 235fb7ed..71dc168d 100644 --- a/src/check_update.c +++ b/src/check_update.c @@ -47,7 +47,7 @@ enum swupd_code check_update() int current_version, server_version; enum swupd_code ret; - ret = read_versions(¤t_version, &server_version, globals.path_prefix); + ret = read_versions(¤t_version, &server_version, globals.path_prefix, true); if (current_version > 0) { info("Current OS version: %d\n", current_version); diff --git a/src/swupd.h b/src/swupd.h index 0389f033..04a8c3f2 100644 --- a/src/swupd.h +++ b/src/swupd.h @@ -161,7 +161,8 @@ extern int main_verify(int current_version); extern enum swupd_code walk_tree(struct manifest *, const char *, bool, const regex_t *, struct file_counts *); extern int get_latest_version(char *v_url); -extern enum swupd_code read_versions(int *current_version, int *server_version, char *path_prefix); +extern int get_absolute_latest_version(void); +extern enum swupd_code read_versions(int *current_version, int *server_version, char *path_prefix, bool absolute); extern int get_current_version(char *path_prefix); extern bool get_distribution_string(char *path_prefix, char *dist); diff --git a/src/update.c b/src/update.c index 59af720d..6f4215ff 100644 --- a/src/update.c +++ b/src/update.c @@ -203,7 +203,7 @@ static enum swupd_code check_versions(int *current_version, int *server_version, { int ret; - ret = read_versions(current_version, server_version, path_prefix); + ret = read_versions(current_version, server_version, path_prefix, false); if (ret != SWUPD_OK) { return ret; } diff --git a/src/version.c b/src/version.c index a44d9283..4568183d 100644 --- a/src/version.c +++ b/src/version.c @@ -31,6 +31,33 @@ #include "config.h" #include "swupd.h" +static int get_version_from_url(char *url) +{ +#define MAX_VERSION_STR_SIZE 11 + + int ret; + int err; + char version_str[MAX_VERSION_STR_SIZE]; + struct curl_file_data tmp_version = { + MAX_VERSION_STR_SIZE, 0, + version_str + }; + + ret = swupd_curl_get_file_memory(url, &tmp_version); + if (ret) { + goto out; + } else { + tmp_version.data[tmp_version.len] = '\0'; + err = strtoi_err(tmp_version.data, &ret); + if (err != 0) { + ret = -1; + } + } + +out: + return ret; +} + /* this function attempts to download the latest server version string file from * the preferred server to a memory buffer, returning either a negative integer * error code or >= 0 representing the server version @@ -41,17 +68,8 @@ * the global version_url is used and the cached version is ignored. */ int get_latest_version(char *v_url) { -#define MAX_VERSION_CHARS 10 -#define MAX_VERSION_STR_SIZE 11 - char *url = NULL; int ret = 0; - int err; - char version_str[MAX_VERSION_STR_SIZE]; - struct curl_file_data tmp_version = { - MAX_VERSION_STR_SIZE, 0, - version_str - }; static int cached_version = -1; if (cached_version > 0 && v_url == NULL) { @@ -63,22 +81,24 @@ int get_latest_version(char *v_url) } string_or_die(&url, "%s/version/format%s/latest", v_url, globals.format_string); - - ret = swupd_curl_get_file_memory(url, &tmp_version); - if (ret) { - goto out; - } else { - tmp_version.data[tmp_version.len] = '\0'; - err = strtoi_err(tmp_version.data, &ret); - - if (err != 0) { - ret = -1; - } - } - -out: + ret = get_version_from_url(url); free_string(&url); cached_version = ret; + + return ret; +} + +/* gets the latest version of the update content regardless of what format we + * are currently in */ +int version_get_absolute_latest(void) +{ + char *url = NULL; + int ret; + + string_or_die(&url, "%s/version/latest_version", globals.version_url); + ret = get_version_from_url(url); + free_string(&url); + return ret; } @@ -175,10 +195,14 @@ bool get_distribution_string(char *path_prefix, char *dist) return true; } -enum swupd_code read_versions(int *current_version, int *server_version, char *path_prefix) +enum swupd_code read_versions(int *current_version, int *server_version, char *path_prefix, bool absolute) { *current_version = get_current_version(path_prefix); - *server_version = get_latest_version(NULL); + if (absolute) { + *server_version = version_get_absolute_latest(); + } else { + *server_version = get_latest_version(NULL); + } if (*current_version < 0) { error("Unable to determine current OS version\n"); diff --git a/test/functional/checkupdate/chk-update-format-bump.bats b/test/functional/checkupdate/chk-update-format-bump.bats new file mode 100755 index 00000000..ce8f0851 --- /dev/null +++ b/test/functional/checkupdate/chk-update-format-bump.bats @@ -0,0 +1,32 @@ +#!/usr/bin/env bats + +# Author: Castulo Martinez +# Email: castulo.martinez@intel.com + +load "../testlib" + +test_setup() { + + create_test_environment -r "$TEST_NAME" 10 1 + bump_format "$TEST_NAME" + create_version -r "$TEST_NAME" 40 30 2 + +} + +@test "CHK010: Check for available updates accross format bumps" { + + # check-update should return the latest available version regardless + # of if it is in a different format + + run sudo sh -c "$SWUPD check-update $SWUPD_OPTS" + + assert_status_is "$SWUPD_OK" + expected_output=$(cat <<-EOM + Current OS version: 10 + Latest server version: 40 + There is a new OS version available: 40 + EOM + ) + assert_is_output "$expected_output" + +} diff --git a/test/functional/testlib.bash b/test/functional/testlib.bash index 93f90f5b..e422d202 100644 --- a/test/functional/testlib.bash +++ b/test/functional/testlib.bash @@ -1356,6 +1356,7 @@ create_version() { # swupd_function sudo mkdir -p "$env_name"/web-dir/"$version"/{files,delta} sudo mkdir -p "$env_name"/web-dir/version/format"$format" write_to_protected_file "$env_name"/web-dir/version/format"$format"/latest "$version" + write_to_protected_file "$env_name"/web-dir/version/latest_version "$version" if [ "$format" = staging ]; then format=1 fi diff --git a/test/functional/update/update-status-no-target-content.bats b/test/functional/update/update-status-no-target-content.bats index 6c692c66..87fe5cbd 100755 --- a/test/functional/update/update-status-no-target-content.bats +++ b/test/functional/update/update-status-no-target-content.bats @@ -5,7 +5,7 @@ load "../testlib" test_setup() { create_test_environment -e "$TEST_NAME" - set_latest_version "$TEST_NAME" 100 + create_version "$TEST_NAME" 100 sudo rm -f "$TARGETDIR"/usr/lib/os-release } diff --git a/test/functional/update/update-status.bats b/test/functional/update/update-status.bats index 1e7abc5a..1266135d 100755 --- a/test/functional/update/update-status.bats +++ b/test/functional/update/update-status.bats @@ -5,7 +5,7 @@ load "../testlib" global_setup() { create_test_environment -e "$TEST_NAME" - set_latest_version "$TEST_NAME" 100 + create_version "$TEST_NAME" 100 }