Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Feature/refactor bundle cache #476

Merged
merged 103 commits into from
Apr 6, 2023
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
Show all changes
103 commits
Select commit Hold shift + click to select a range
7953593
Revert to -O0 instead of -Og for DEBUG, because -Og optimizes out deb…
pnoltes Jan 31, 2023
16b119b
Improve utils lib with string convert, file touch and file modified f…
pnoltes Jan 31, 2023
3952f49
Refactor framework to support bundle zip updates based on modified st…
pnoltes Jan 31, 2023
e1a6dc6
Update coverage ci config to show test output on failures
pnoltes Jan 31, 2023
7f858a7
Add small sleep to ensure time diff can be measured in bundle archive…
pnoltes Jan 31, 2023
325a20c
Merge branch 'master' into feature/refactor_bundle_cache
pnoltes Feb 5, 2023
3d8785a
Add initial setup for bundle archive test with error injection
pnoltes Feb 6, 2023
f741665
Link the code under test statically into the testing executable to ma…
PengZheng Feb 7, 2023
6c94c9b
Minor documentation correction.
PengZheng Feb 7, 2023
2d82cbf
Use Ubuntu 22.04 for build-apt.
PengZheng Feb 7, 2023
c2932cd
Revert "Use Ubuntu 22.04 for build-apt."
PengZheng Feb 7, 2023
04fae83
Use Debug for build-apt.
PengZheng Feb 7, 2023
0cf6420
Minor documentation improvement.
PengZheng Feb 7, 2023
c6cbbe0
Merge branch 'master' into feature/refactor_bundle_cache
PengZheng Feb 7, 2023
d0c6f2c
Extend error injections test for bundle archive creation
pnoltes Feb 7, 2023
3aa39be
Add some extra error injection tests
pnoltes Feb 14, 2023
b0eb4bc
Add additional error injection to increase code coverage.
pnoltes Feb 17, 2023
fb1ffd2
Fix memleak in bundle archive error handling
pnoltes Feb 18, 2023
b17cc66
Merge remote-tracking branch 'origin/master' into feature/refactor_bu…
pnoltes Feb 19, 2023
69d8511
Remove extra `bundle_update`.
PengZheng Feb 20, 2023
8ebff51
Simplify startCommand_execute implementation.
PengZheng Feb 21, 2023
b44c58b
Extract common Bundle Command Execution.
PengZheng Feb 21, 2023
639a7ad
Non-existent bundle id is not an error.
PengZheng Feb 21, 2023
f20b1b4
Minor typo fix.
PengZheng Feb 21, 2023
5233dab
Replace CELIX_EI_IMPL0 by CELIX_EI_IMPL.
PengZheng Feb 21, 2023
f519ba8
Fix incorrect use of asprintf with va_list.
PengZheng Feb 21, 2023
aab52cc
Apply double close of shared library fix from PR #480
pnoltes Feb 21, 2023
23747f3
Fix incorrect documentation of CELIX_FRAMEWORK_AUTO_START_0 in framew…
pnoltes Feb 21, 2023
a0c23d0
Simplify getting a manifest entry in http admin by using celix_bundle…
pnoltes Feb 21, 2023
e55ea9c
Avoid `celix_bundle_getEntry` for bundles without "X-Web-Resource" ma…
PengZheng Feb 22, 2023
3992e53
Avoid unnecessary `celix_bundle_getId`.
PengZheng Feb 22, 2023
4362479
Avoid unnecessary `celix_bundle_getId` and `httpAdmin_updateInfoSvc` …
PengZheng Feb 22, 2023
65aece5
Add synchronization to avoid hangs (#482) if possible.
PengZheng Feb 22, 2023
b6646bf
Stick to Conan 1.59.0.
PengZheng Feb 22, 2023
3e6af3b
Fix http_admin_start return value.
PengZheng Feb 22, 2023
38176b6
Fire and forget bundle lifecycle handler.
PengZheng Feb 23, 2023
cb2501b
Merge remote-tracking branch 'apache/feature/refactor_bundle_cache' i…
PengZheng Feb 23, 2023
a6f9144
Merge remote-tracking branch 'apache/master' into feature/refactor_bu…
PengZheng Feb 24, 2023
9b825ee
Update bundle cache doxygen documentation for the updated framework c…
pnoltes Feb 25, 2023
559d3d9
Improve doxygen of celix_bundle_context
pnoltes Feb 25, 2023
9a1cde3
Improve celix_bundle_context doxygen
pnoltes Feb 25, 2023
cd28d5e
Reintroduce removed bundle revision function
pnoltes Feb 25, 2023
c2cf1e4
Minor code improvement for launcher.
PengZheng Feb 25, 2023
1a0e6d9
Merge remote-tracking branch 'apache/feature/refactor_bundle_cache' i…
PengZheng Feb 25, 2023
fefacec
Remove framework arg from module create and improve some doxygen doc
pnoltes Feb 25, 2023
6b85ef7
Merge branch 'feature/refactor_bundle_cache' of github.com:apache/cel…
pnoltes Feb 25, 2023
35a1bc8
Improve doxygen and markdown documentation
pnoltes Feb 25, 2023
d0065c2
Add usage of celix_framework_getConfigProperty to framework create
pnoltes Feb 25, 2023
b28feee
Remove unused commented-out code
pnoltes Feb 28, 2023
684bef5
Improve doxygen
pnoltes Feb 28, 2023
90c22a5
Improve doxygen
pnoltes Feb 28, 2023
481645e
Don't follow symbolic links when deleting directory recursively.
PengZheng Feb 28, 2023
3705a7c
Merge remote-tracking branch 'apache/feature/refactor_bundle_cache' i…
PengZheng Feb 28, 2023
3873c15
Add test for tmp bundle cache.
PengZheng Mar 10, 2023
b5cebda
Merge branch 'master' into feature/refactor_bundle_cache
PengZheng Mar 10, 2023
1425913
Add test to create directory with absolute path.
PengZheng Mar 10, 2023
8e2b7b8
Update API documentation for bundle cache.
PengZheng Mar 13, 2023
77e5ab5
Remove possible dead code in framework_logIfError
PengZheng Mar 13, 2023
bee8169
Merge branch 'master' into feature/refactor_bundle_cache
PengZheng Mar 15, 2023
b8e54de
FIx incorrect doxygen entry
pnoltes Mar 16, 2023
1b86bf8
Rename celix_utils_freeStringIfNeeded
pnoltes Mar 16, 2023
0079f90
Improve argument handling for bundleCommand_execute
pnoltes Mar 16, 2023
09615f8
Align celix_utils_convertStringToVersion with other convert functions
pnoltes Mar 16, 2023
bcff7cf
Fix invalid main return codes in celix_launcher
pnoltes Mar 16, 2023
5e8ed19
Minor improvement of bundleCommand_execute.
PengZheng Mar 17, 2023
9e8ccec
Fix corner case memory leak for celix_bundleCache_createArchive.
PengZheng Mar 17, 2023
fe385f0
Minor improvement of celix_bundleCache_createArchive.
PengZheng Mar 17, 2023
350144f
Add more test cases for error condition.
PengZheng Mar 17, 2023
113930c
Minor improvement of bundleRevision.
PengZheng Mar 20, 2023
0119850
Remove unused bundleStateProperties from bundle archive obj
pnoltes Mar 21, 2023
8176e26
Remove revision nr of usage multiple revision in bundle archive
pnoltes Mar 21, 2023
bc91e8b
Minor code improvement.
PengZheng Mar 23, 2023
381f7ad
Fix corner case deadlock and simplify `celix_bundleArchive_getLastMod…
PengZheng Mar 24, 2023
ddcafa5
Minor improvement of `celix_bundleArchive_extractBundle`
PengZheng Mar 24, 2023
b98fc0d
Avoid memory allocation in `celix_utils_extractZipInternal` and impro…
PengZheng Mar 27, 2023
de7f5c7
Embed libzip error code into Celix error code.
PengZheng Mar 28, 2023
9880b03
Fix memory leak when trying to extract bad embedded data.
PengZheng Mar 28, 2023
b4dbbd7
Test celix_utils_extractZipInternal thoroughly.
PengZheng Mar 28, 2023
5c77b0b
Fix compilation error.
PengZheng Mar 28, 2023
8a6ec90
Reduce dynamic memory allocation in celix_utils_createDirectory.
PengZheng Mar 29, 2023
3882af5
Fix some small race conditions, mem leaks and commented out code
pnoltes Mar 30, 2023
5758ab4
Merge remote-tracking branch 'origin/master' into feature/refactor_bu…
pnoltes Mar 30, 2023
a467814
Update for renamed CELIX_EI_IMPL call
pnoltes Mar 30, 2023
c4701aa
Remove bundleArchive_setLastModified usage for bundle uninstall
pnoltes Mar 30, 2023
c25ca97
Make the framework independent of dfi.
PengZheng Mar 31, 2023
3bb5ea1
Test celix_utils_deleteDirectory thoroughly.
PengZheng Mar 31, 2023
e9734f2
Test celix_utils_createDirectory thoroughly.
PengZheng Mar 31, 2023
27a5bbb
Merge remote-tracking branch 'apache/feature/refactor_bundle_cache' i…
PengZheng Mar 31, 2023
d41233b
Improve celix convert utils for whitespace and incorrect trailing cha…
pnoltes Mar 31, 2023
6853350
Refactor lb command to use celix_bundleContext_useBundles instead of …
pnoltes Mar 31, 2023
8bad0fa
Optimize celix_utils_deleteDirectory to eliminate recursion and dynam…
PengZheng Mar 31, 2023
af8948f
Merge remote-tracking branch 'apache/feature/refactor_bundle_cache' i…
PengZheng Mar 31, 2023
0d3e3d7
Optimize celix_utils_deleteDirectory to eliminate `stat` calls and te…
pnoltes Mar 31, 2023
7e2f4e8
Fix bug in bundles/shell/shell/src/lb_command.c
pnoltes Apr 3, 2023
e297073
Remove incorrect oxygen
pnoltes Apr 3, 2023
696df62
Remove usage of deprecated celix array list function
pnoltes Apr 3, 2023
f9feb17
Add new getLocation function to prevent use-after-free scenarios
pnoltes Apr 3, 2023
f0f53f9
gh-486: Remove [[nodiscard]] usage (c++17 only)
pnoltes Apr 3, 2023
0f0ab31
Refactor lb command to use the array_list_options
pnoltes Apr 3, 2023
a9d2726
Replace try/catch with unique_ptr with custom deleter
pnoltes Apr 3, 2023
0444e0e
Improve error handling of celix_framework_utils.c and add correspondi…
PengZheng Apr 3, 2023
64f2fa7
Merge remote-tracking branch 'apache/feature/refactor_bundle_cache' i…
PengZheng Apr 3, 2023
0decde3
Optimize celix_framework_utils_extractBundleEmbedded and test it thor…
PengZheng Apr 4, 2023
File filter

Filter by extension

Filter by extension


Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
2 changes: 1 addition & 1 deletion .github/workflows/ubuntu.yml
Original file line number Diff line number Diff line change
Expand Up @@ -109,7 +109,7 @@ jobs:
-DRSA_SHM=ON
-DRSA_REMOTE_SERVICE_ADMIN_SHM_V2=ON
-DSHELL_BONJOUR=ON
-DCMAKE_BUILD_TYPE=Release
-DCMAKE_BUILD_TYPE=Debug
PengZheng marked this conversation as resolved.
Show resolved Hide resolved
run: |
mkdir build install
cd build
Expand Down
4 changes: 2 additions & 2 deletions CMakeLists.txt
Original file line number Diff line number Diff line change
Expand Up @@ -149,8 +149,8 @@ endif()

# Set build type specific flags
# Debug
set(CMAKE_C_FLAGS_DEBUG "-g -DDEBUG -Og ${CMAKE_C_FLAGS}")
set(CMAKE_CXX_FLAGS_DEBUG "-g -DDEBUG -Og ${CMAKE_CXX_FLAGS}")
set(CMAKE_C_FLAGS_DEBUG "-g -DDEBUG -O0 ${CMAKE_C_FLAGS}")
set(CMAKE_CXX_FLAGS_DEBUG "-g -DDEBUG -O0 ${CMAKE_CXX_FLAGS}")
set(CMAKE_DEBUG_POSTFIX "d")

if (CMAKE_BUILD_TYPE STREQUAL "Debug")
Expand Down
7 changes: 4 additions & 3 deletions bundles/deployment_admin/src/deployment_admin.c
Original file line number Diff line number Diff line change
Expand Up @@ -32,6 +32,7 @@
#include <curl/easy.h>
#include <stdbool.h>
#include <uuid/uuid.h>
#include <celix_bundle_context.h>


#include "deployment_admin.h"
Expand Down Expand Up @@ -581,10 +582,10 @@ celix_status_t deploymentAdmin_updateDeploymentPackageBundles(deployment_admin_p
deploymentPackage_getBundle(source, info->symbolicName, &updateBundle);
if (updateBundle != NULL) {
//printf("Update bundle from: %s\n", bundlePath);
bundle_update(updateBundle, bundlePath);
celix_bundleContext_updateBundle(admin->context, celix_bundle_getId(updateBundle), bundlePath);
} else {
//printf("Install bundle from: %s\n", bundlePath);
bundleContext_installBundle2(admin->context, bsn, bundlePath, &updateBundle);
celix_bundleContext_installBundle(admin->context, bundlePath, false);
}

free(entry);
Expand Down Expand Up @@ -674,7 +675,7 @@ celix_status_t deploymentAdmin_processDeploymentPackageResources(deployment_admi
bundle_getEntry(bundle, "/", &entry);
deploymentPackage_getName(source, &name);

int length = strlen(entry) + strlen(name) + strlen(info->path) + 7;
length = strlen(entry) + strlen(name) + strlen(info->path) + 7;
char resourcePath[length];
snprintf(resourcePath, length, "%srepo/%s/%s", entry, name, info->path);
deploymentPackage_getName(source, &packageName);
Expand Down
1 change: 1 addition & 0 deletions bundles/http_admin/gtest/CMakeLists.txt
Original file line number Diff line number Diff line change
Expand Up @@ -41,6 +41,7 @@ target_compile_definitions(http_websocket_tests PRIVATE
HTTP_ADMIN_SUT_BUNDLE="${HTTP_ADMIN_SUT_BUNDLE}"
)
target_link_libraries(http_websocket_tests PRIVATE Celix::framework Celix::http_admin_api GTest::gtest GTest::gtest_main)
add_celix_bundle_dependencies(http_websocket_tests Celix::http_admin http_admin_sut)

add_test(NAME http_websocket_tests COMMAND http_websocket_tests)
setup_target_for_coverage(http_websocket_tests SCAN_DIR ../http_admin)
Expand Down
2 changes: 1 addition & 1 deletion bundles/http_admin/gtest/src/http_websocket_tests.cc
Original file line number Diff line number Diff line change
Expand Up @@ -76,7 +76,7 @@ static void checkHttpRequest(const char* req_str, int expectedReturnCode) {
//If response is successful, check if the received response contains the info we expected
auto response_info = mg_get_response_info(connection);
EXPECT_TRUE(response_info != nullptr);
EXPECT_EQ(expectedReturnCode, response_info->status_code);
EXPECT_EQ(expectedReturnCode, response_info->status_code) << "Unexpected return code for request: " << req_str;

mg_close_connection(connection);
}
Expand Down
2 changes: 0 additions & 2 deletions bundles/http_admin/http_admin/CMakeLists.txt
Original file line number Diff line number Diff line change
Expand Up @@ -30,8 +30,6 @@ add_celix_bundle(http_admin
target_include_directories(http_admin PRIVATE src)

target_link_libraries(http_admin PUBLIC Celix::http_admin_api)
file(MAKE_DIRECTORY resources)
celix_bundle_add_dir(http_admin resources/ DESTINATION root/)

celix_deprecated_utils_headers(http_admin)

Expand Down
41 changes: 27 additions & 14 deletions bundles/http_admin/http_admin/src/activator.c
Original file line number Diff line number Diff line change
Expand Up @@ -16,26 +16,18 @@
* specific language governing permissions and limitations
* under the License.
*/
/**
* activator.c
*
* \date May 24, 2019
* \author <a href="mailto:[email protected]">Apache Celix Project Team</a>
* \copyright Apache License, Version 2.0
*/

#include <stdlib.h>
#include <memory.h>

#include "celix_api.h"
#include "celix_types.h"

#include "http_admin.h"
#include "websocket_admin.h"

#include "http_admin/api.h"
#include "http_admin_constants.h"
#include "civetweb.h"
#include "celix_file_utils.h"


typedef struct http_admin_activator {
Expand All @@ -52,7 +44,28 @@ typedef struct http_admin_activator {

static int http_admin_start(http_admin_activator_t *act, celix_bundle_context_t *ctx) {
celix_bundle_t *bundle = celix_bundleContext_getBundle(ctx);
char* root = celix_bundle_getEntry(bundle, "root");
char* storeRoot = celix_bundle_getDataFile(bundle, "");
if (storeRoot == NULL) {
celix_bundleContext_log(ctx, CELIX_LOG_LEVEL_ERROR, "Cannot get bundle store root for the http admin bundle.");
return CELIX_BUNDLE_EXCEPTION;
}

char* httpRoot = NULL;
int rc = asprintf(&httpRoot, "%s/root", storeRoot);
if (rc < 0) {
celix_bundleContext_log(ctx, CELIX_LOG_LEVEL_ERROR, "Cannot create http root directory for the http admin bundle.");
free(storeRoot);
return CELIX_ENOMEM;
}
free(storeRoot);

celix_status_t status = celix_utils_createDirectory(httpRoot, false, NULL);
if (status != CELIX_SUCCESS) {
celix_bundleContext_log(ctx, CELIX_LOG_LEVEL_ERROR, "Cannot create http root directory for the http admin bundle.");
free(httpRoot);
return status;
}
celix_bundleContext_log(ctx, CELIX_LOG_LEVEL_DEBUG, "Using http root directory %s", httpRoot);

bool prop_use_websockets = celix_bundleContext_getPropertyAsBool(ctx, HTTP_ADMIN_USE_WEBSOCKETS_KEY, HTTP_ADMIN_USE_WEBSOCKETS_DFT);
long listPort = celix_bundleContext_getPropertyAsLong(ctx, HTTP_ADMIN_LISTENING_PORTS_KEY, HTTP_ADMIN_LISTENING_PORTS_DFT);
Expand All @@ -72,22 +85,22 @@ static int http_admin_start(http_admin_activator_t *act, celix_bundle_context_t
act->useWebsockets = prop_use_websockets;

const char *svr_opts[] = {
"document_root", root,
"document_root", httpRoot,
"listening_ports", prop_port,
"websocket_timeout_ms", prop_timeout,
"websocket_root", root,
"websocket_root", httpRoot,
"num_threads", prop_num_threads,
NULL
};

//Try the 'LISTENING_PORT' property first, if failing continue with the port range functionality
act->httpManager = httpAdmin_create(ctx, root, svr_opts);
act->httpManager = httpAdmin_create(ctx, httpRoot, svr_opts);

for(long port = prop_port_min; act->httpManager == NULL && port <= prop_port_max; port++) {
char *port_str;
asprintf(&port_str, "%li", port);
svr_opts[3] = port_str;
act->httpManager = httpAdmin_create(ctx, root, svr_opts);
act->httpManager = httpAdmin_create(ctx, httpRoot, svr_opts);
PengZheng marked this conversation as resolved.
Show resolved Hide resolved
free(port_str);
}

Expand Down
44 changes: 13 additions & 31 deletions bundles/http_admin/http_admin/src/http_admin.c
Original file line number Diff line number Diff line change
Expand Up @@ -16,13 +16,6 @@
* specific language governing permissions and limitations
* under the License.
*/
/**
* http_admin.c
*
* \date May 24, 2019
* \author <a href="mailto:[email protected]">Apache Celix Project Team</a>
* \copyright Apache License, Version 2.0
*/

#include <stdlib.h>
#include <memory.h>
Expand Down Expand Up @@ -480,33 +473,22 @@ static bool aliasList_containsAlias(celix_array_list_t *alias_list, const char *
}

void http_admin_startBundle(void *data, const celix_bundle_t *bundle) {
bundle_archive_pt archive = NULL;
bundle_revision_pt revision = NULL;
manifest_pt manifest = NULL;

http_admin_manager_t *admin = data;

// Retrieve manifest from current bundle revision (retrieve revision from bundle archive) to check for
// Amdatu pattern manifest property X-Web-Resource. This property is used for aliases.
celix_status_t status = bundle_getArchive((celix_bundle_t*)bundle, &archive);
if(status == CELIX_SUCCESS && archive != NULL) {
status = bundleArchive_getCurrentRevision(archive, &revision);
const char* aliases = celix_bundle_getManifestValue(bundle, "X-Web-Resource");
PengZheng marked this conversation as resolved.
Show resolved Hide resolved
if (aliases == NULL) {
celix_bundleContext_log(admin->context, CELIX_LOG_LEVEL_TRACE, "No aliases found for bundle %s",
celix_bundle_getSymbolicName(bundle));
return;
}

if(status == CELIX_SUCCESS && revision != NULL) {
status = bundleRevision_getManifest(revision, &manifest);
}

if(status == CELIX_SUCCESS && manifest != NULL) {
const char *aliases = NULL;
const char *revision_root = NULL;
long bnd_id;

aliases = manifest_getValue(manifest, "X-Web-Resource");
bnd_id = celix_bundle_getId(bundle);
bundleRevision_getRoot(revision, &revision_root);
createAliasesSymlink(aliases, admin->root, revision_root, bnd_id, admin->aliasList);
char* bundleRoot = celix_bundle_getEntry(bundle, "");
if (bundleRoot == NULL) {
celix_bundleContext_log(admin->context, CELIX_LOG_LEVEL_ERROR, "No root for bundle %s",
celix_bundle_getSymbolicName(bundle));
return;
}
long bndId = celix_bundle_getId(bundle);
createAliasesSymlink(aliases, admin->root, bundleRoot, bndId, admin->aliasList);
free(bundleRoot);
httpAdmin_updateInfoSvc(admin);
}

Expand Down
7 changes: 0 additions & 7 deletions bundles/http_admin/http_admin/src/websocket_admin.c
Original file line number Diff line number Diff line change
Expand Up @@ -16,13 +16,6 @@
* specific language governing permissions and limitations
* under the License.
*/
/**
* websocket_admin.c
*
* \date May 24, 2019
* \author <a href="mailto:[email protected]">Apache Celix Project Team</a>
* \copyright Apache License, Version 2.0
*/

#include <stdlib.h>
#include <memory.h>
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -51,5 +51,8 @@ celix_get_bundle_file(Celix::rsa_discovery RSA_DISCOVERY_BUNDLE_FILE)
configure_file(resources/client.properties.in client.properties)
configure_file(resources/server.properties.in server.properties)


add_celix_bundle_dependencies(test_rsa_shm Celix::rsa_shm Celix::rsa_json_rpc calculator_shell calculator)

add_test(NAME run_test_rsa_shm COMMAND test_rsa_shm)
setup_target_for_coverage(test_rsa_shm SCAN_DIR ..)
Original file line number Diff line number Diff line change
Expand Up @@ -42,7 +42,7 @@ target_link_libraries(test_tm_scoped PRIVATE
Celix::rsa_common
)

add_celix_bundle_dependencies(test_tm_scoped Celix::rsa_dfi Celix::rsa_topology_manager)
add_celix_bundle_dependencies(test_tm_scoped Celix::rsa_dfi Celix::rsa_topology_manager calculator topology_manager_disc_mock_bundle topology_manager_test_bundle)

file(GENERATE
OUTPUT "${CMAKE_CURRENT_BINARY_DIR}/config.properties"
Expand Down
2 changes: 1 addition & 1 deletion bundles/shell/shell/CMakeLists.txt
Original file line number Diff line number Diff line change
Expand Up @@ -46,7 +46,7 @@ if (SHELL)
src/query_command.c
src/quit_command.c
src/std_commands.c
)
src/bundle_command.c)
target_include_directories(shell_commands PRIVATE src)
target_link_libraries(shell_commands PRIVATE Celix::shell_api Celix::log_helper)
celix_deprecated_utils_headers(shell_commands)
Expand Down
20 changes: 14 additions & 6 deletions bundles/shell/shell/gtest/src/ShellTestSuite.cc
Original file line number Diff line number Diff line change
Expand Up @@ -78,9 +78,9 @@ static void callCommand(std::shared_ptr<celix_bundle_context_t>& ctx, const char
EXPECT_TRUE(shell != nullptr);
celix_status_t status = shell->executeCommand(shell->handle, d->cmdLine, stdout, stderr);
if (d->cmdShouldSucceed) {
EXPECT_EQ(CELIX_SUCCESS, status);
EXPECT_EQ(CELIX_SUCCESS, status) << "Command '" << d->cmdLine << "' should succeed";
} else {
EXPECT_TRUE(status != CELIX_SUCCESS);
EXPECT_NE(CELIX_SUCCESS, status) << "Command '" << d->cmdLine << "' should not succeed";
}
};
bool called = celix_bundleContext_useServiceWithOptions(ctx.get(), &opts);
Expand All @@ -98,10 +98,18 @@ TEST_F(ShellTestSuite, testAllCommandsAreCallable) {
callCommand(ctx, "lb -l", true);
callCommand(ctx, "query", true);
callCommand(ctx, "q -v", true);
callCommand(ctx, "stop 15", false);
callCommand(ctx, "start 15", false);
callCommand(ctx, "uninstall 15", false);
callCommand(ctx, "update 15", false);
callCommand(ctx, "stop not-a-number", false);
callCommand(ctx, "stop", false); // incorrect number of arguments
callCommand(ctx, "start not-a-number", false);
callCommand(ctx, "start", false); // incorrect number of arguments
callCommand(ctx, "uninstall not-a-number", false);
callCommand(ctx, "uninstall", false); // incorrect number of arguments
callCommand(ctx, "update not-a-number", false);
callCommand(ctx, "update", false); // incorrect number of arguments
callCommand(ctx, "stop 15", false); //non existing bundle id
callCommand(ctx, "start 15", false); //non existing bundle id
callCommand(ctx, "uninstall 15", false); //non existing bundle id
callCommand(ctx, "update 15", false); //non existing bundle id
}

TEST_F(ShellTestSuite, quitTest) {
Expand Down
72 changes: 72 additions & 0 deletions bundles/shell/shell/src/bundle_command.c
Original file line number Diff line number Diff line change
@@ -0,0 +1,72 @@
/*
Licensed to the Apache Software Foundation (ASF) under one
or more contributor license agreements. See the NOTICE file
distributed with this work for additional information
regarding copyright ownership. The ASF licenses this file
to you under the Apache License, Version 2.0 (the
"License"); you may not use this file except in compliance
with the License. You may obtain a copy of the License at

http://www.apache.org/licenses/LICENSE-2.0

Unless required by applicable law or agreed to in writing,
software distributed under the License is distributed on an
"AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY
KIND, either express or implied. See the License for the
specific language governing permissions and limitations
under the License.
*/

#include "bundle_command.h"
#include "celix_bundle_context.h"
#include "celix_convert_utils.h"
#include "celix_utils.h"
#include <stdlib.h>
#include <string.h>

bool bundleCommand_execute(void *handle, const char *constCommandLine, FILE *outStream, FILE *errStream, bundle_control_fpt ctrl) {
celix_bundle_context_t *ctx = handle;

char* sub = NULL;
char* savePtr = NULL;
char* command = celix_utils_strdup(constCommandLine);
strtok_r(command, OSGI_SHELL_COMMAND_SEPARATOR, &savePtr); //ignore command name
sub = strtok_r(NULL, OSGI_SHELL_COMMAND_SEPARATOR, &savePtr);
celix_array_list_t* bundleIds = celix_arrayList_create();
bool validArgs = true;

if (sub == NULL) {
fprintf(errStream, "Incorrect number of arguments.\n");
validArgs = false;
}

for (; sub != NULL; sub = strtok_r(NULL, OSGI_SHELL_COMMAND_SEPARATOR, &savePtr)) {
bool converted;
long bndId = celix_utils_convertStringToLong(sub, 0, &converted);
if (!converted) {
validArgs = false;
fprintf(errStream, "Cannot convert '%s' to long (bundle id).\n", sub);
continue;
stegemr marked this conversation as resolved.
Show resolved Hide resolved
}
if (!celix_bundleContext_isBundleInstalled(ctx, bndId)) {
validArgs = false;
fprintf(outStream, "No bundle with id %li.\n", bndId);
continue;
}
celix_arrayList_addLong(bundleIds, bndId);
}
free(command);

if (!validArgs) {
goto cleanup;
}
for (int i = 0; i < celix_arrayList_size(bundleIds); i++) {
long bndId = celix_arrayList_getLong(bundleIds, i);
celix_framework_t* fw = celix_bundleContext_getFramework(ctx);
ctrl(fw, bndId);
}

cleanup:
celix_arrayList_destroy(bundleIds);
return validArgs;
}
Loading