From 187332b2fa169056a2c3682d9a7628d872b2d49b Mon Sep 17 00:00:00 2001 From: Daniel Pfeifer Date: Sat, 17 Jun 2017 12:22:53 +0200 Subject: cmServerProtocol: fix test of empty values If a required value is in the cache, it is not necessary to set it explicitly. Fixes: #16948, #16988 --- Help/manual/cmake-server.7.rst | 4 +++- Source/cmServerProtocol.cxx | 15 ++++++++------- 2 files changed, 11 insertions(+), 8 deletions(-) diff --git a/Help/manual/cmake-server.7.rst b/Help/manual/cmake-server.7.rst index f6d3032..6c0e6aa 100644 --- a/Help/manual/cmake-server.7.rst +++ b/Help/manual/cmake-server.7.rst @@ -277,7 +277,9 @@ Giving the "major" version of the requested protocol version will make the serve use the latest minor version of that protocol. Use this if you do not explicitly need to depend on a specific minor version. -Each protocol version may request additional attributes to be present. +If the build directory already contains a CMake cache, it is sufficient to set +the "buildDirectory" attribute. To create a fresh build directory, additional +attributes are required depending on the protocol version. Protocol version 1.0 requires the following attributes to be set: diff --git a/Source/cmServerProtocol.cxx b/Source/cmServerProtocol.cxx index 7a841a8..606535f 100644 --- a/Source/cmServerProtocol.cxx +++ b/Source/cmServerProtocol.cxx @@ -269,6 +269,10 @@ static bool testHomeDirectory(cmState* state, std::string& value, { const std::string cachedValue = std::string(state->GetCacheEntryValue("CMAKE_HOME_DIRECTORY")); + if (value.empty()) { + value = cachedValue; + return true; + } const std::string suffix = "/CMakeLists.txt"; const std::string cachedValueCML = cachedValue + suffix; const std::string valueCML = value + suffix; @@ -279,9 +283,6 @@ static bool testHomeDirectory(cmState* state, std::string& value, "source directory value.")); return false; } - if (value.empty()) { - value = cachedValue; - } return true; } @@ -292,15 +293,15 @@ static bool testValue(cmState* state, const std::string& key, const char* entry = state->GetCacheEntryValue(key); const std::string cachedValue = entry == nullptr ? std::string() : std::string(entry); - if (!cachedValue.empty() && !value.empty() && cachedValue != value) { + if (value.empty()) { + value = cachedValue; + } + if (!cachedValue.empty() && cachedValue != value) { setErrorMessage(errorMessage, std::string("\"") + key + "\" is set but incompatible with configured " + keyDescription + " value."); return false; } - if (value.empty()) { - value = cachedValue; - } return true; } -- cgit v0.12 From 1df3875871af9aa3f144ab065479b98e255aca5a Mon Sep 17 00:00:00 2001 From: Daniel Pfeifer Date: Sat, 17 Jun 2017 13:37:10 +0200 Subject: cmServerProtocol: allow 'cache' request before 'configure' Fixes: #16989 --- Help/manual/cmake-server.7.rst | 3 +-- Source/cmServerProtocol.cxx | 4 ---- 2 files changed, 1 insertion(+), 6 deletions(-) diff --git a/Help/manual/cmake-server.7.rst b/Help/manual/cmake-server.7.rst index 6c0e6aa..c56e5a7 100644 --- a/Help/manual/cmake-server.7.rst +++ b/Help/manual/cmake-server.7.rst @@ -666,8 +666,7 @@ and will not survive the build directory getting cleaned out. Type "cache" ^^^^^^^^^^^^ -The "cache" request can be used once a project is configured and will -list the cached configuration values. +The "cache" request will list the cached configuration values. Example:: diff --git a/Source/cmServerProtocol.cxx b/Source/cmServerProtocol.cxx index 606535f..b371e9e 100644 --- a/Source/cmServerProtocol.cxx +++ b/Source/cmServerProtocol.cxx @@ -490,10 +490,6 @@ bool cmServerProtocol1::IsExperimental() const cmServerResponse cmServerProtocol1::ProcessCache( const cmServerRequest& request) { - if (this->m_State < STATE_CONFIGURED) { - return request.ReportError("This project was not configured yet."); - } - cmState* state = this->CMakeInstance()->GetState(); Json::Value result = Json::objectValue; -- cgit v0.12 From 9b3c5ccf1200e237c0bad3336235b9dde289f016 Mon Sep 17 00:00:00 2001 From: Daniel Pfeifer Date: Wed, 21 Jun 2017 21:26:09 +0200 Subject: Server: test cache after reconnect --- Tests/Server/CMakeLists.txt | 1 + Tests/Server/cmakelib.py | 39 +++++++++++++++++++++++++++++++++++++++ Tests/Server/server-test.py | 24 +++++++++--------------- Tests/Server/tc_cache.json | 24 ++++++++++++++++++++++++ Tests/Server/tc_handshake.json | 4 ++++ 5 files changed, 77 insertions(+), 15 deletions(-) create mode 100644 Tests/Server/tc_cache.json diff --git a/Tests/Server/CMakeLists.txt b/Tests/Server/CMakeLists.txt index e7eaa8d..2ad05c3 100644 --- a/Tests/Server/CMakeLists.txt +++ b/Tests/Server/CMakeLists.txt @@ -20,6 +20,7 @@ macro(do_test bsname file) endif() endmacro() +do_test("test_cache" "tc_cache.json") do_test("test_handshake" "tc_handshake.json") do_test("test_globalSettings" "tc_globalSettings.json") do_test("test_buildsystem1" "tc_buildsystem1.json") diff --git a/Tests/Server/cmakelib.py b/Tests/Server/cmakelib.py index 78450d5..2218e02 100644 --- a/Tests/Server/cmakelib.py +++ b/Tests/Server/cmakelib.py @@ -95,6 +95,21 @@ def initProc(cmakeCommand): return cmakeCommand +def exitProc(cmakeCommand): + # Tell the server to exit. + cmakeCommand.stdin.close() + cmakeCommand.stdout.close() + + # Wait for the server to exit. + # If this version of python supports it, terminate the server after a timeout. + try: + cmakeCommand.wait(timeout=5) + except TypeError: + cmakeCommand.wait() + except: + cmakeCommand.terminate() + raise + def waitForMessage(cmakeCommand, expected): data = ordered(expected) packet = ordered(waitForRawMessage(cmakeCommand)) @@ -197,3 +212,27 @@ def validateGlobalSettings(cmakeCommand, cmakeCommandPath, data): print("Validating", i) if (packet[i] != data[i]): sys.exit(1) + +def validateCache(cmakeCommand, data): + packet = waitForReply(cmakeCommand, 'cache', '', False) + + cache = packet['cache'] + + if (data['isEmpty']): + if (cache != []): + print('Expected empty cache, but got data.\n') + sys.exit(1) + return; + + if (cache == []): + print('Expected cache contents, but got none.\n') + sys.exit(1) + + hadHomeDir = False + for value in cache: + if (value['key'] == 'CMAKE_HOME_DIRECTORY'): + hadHomeDir = True + + if (not hadHomeDir): + print('No CMAKE_HOME_DIRECTORY found in cache.') + sys.exit(1) diff --git a/Tests/Server/server-test.py b/Tests/Server/server-test.py index 5621111..f5a3f28 100644 --- a/Tests/Server/server-test.py +++ b/Tests/Server/server-test.py @@ -84,7 +84,7 @@ for obj in testData: if 'extraGenerator' in data: extraGenerator = data['extraGenerator'] if not os.path.isabs(buildDirectory): buildDirectory = buildDir + "/" + buildDirectory - if not os.path.isabs(sourceDirectory): + if sourceDirectory != '' and not os.path.isabs(sourceDirectory): sourceDirectory = sourceDir + "/" + sourceDirectory cmakelib.handshake(proc, major, minor, sourceDirectory, buildDirectory, generator, extraGenerator) @@ -95,26 +95,20 @@ for obj in testData: if not 'generator' in data: data['generator'] = cmakeGenerator if not 'extraGenerator' in data: data['extraGenerator'] = '' cmakelib.validateGlobalSettings(proc, cmakeCommand, data) + elif 'validateCache' in obj: + data = obj['validateCache'] + if not 'isEmpty' in data: data['isEmpty'] = false + cmakelib.validateCache(proc, data) elif 'message' in obj: print("MESSAGE:", obj["message"]) + elif 'reconnect' in obj: + cmakelib.exitProc(proc) + proc = cmakelib.initProc(cmakeCommand) else: print("Unknown command:", json.dumps(obj)) sys.exit(2) print("Completed") -# Tell the server to exit. -proc.stdin.close() -proc.stdout.close() - -# Wait for the server to exit. -# If this version of python supports it, terminate the server after a timeout. -try: - proc.wait(timeout=5) -except TypeError: - proc.wait() -except: - proc.terminate() - raise - +cmakelib.exitProc(proc) sys.exit(proc.returncode) diff --git a/Tests/Server/tc_cache.json b/Tests/Server/tc_cache.json new file mode 100644 index 0000000..74af6d9 --- /dev/null +++ b/Tests/Server/tc_cache.json @@ -0,0 +1,24 @@ +[ +{ "message": "Testing cache" }, + +{ "message": "Cache after first handshake is empty:" }, +{ "handshake": {"major": 1, "sourceDirectory": "buildsystem1", "buildDirectory": "buildsystem1"} }, +{ "send": { "type": "cache" } }, +{ "validateCache": { "isEmpty": true } }, + +{ "message": "Cache after configure is populated:" }, +{ "send": { "type": "configure" } }, +{ "reply": { "type": "configure", "skipProgress":true } }, +{ "send": { "type": "cache" } }, +{ "validateCache": { "isEmpty": false } }, + +{ "message": "Handshake for existing cache requires buildDirectory only:" }, +{ "reconnect": {} }, +{ "handshake": {"major": 1, "sourceDirectory": "", "buildDirectory": "buildsystem1"} }, + +{ "message": "Cache after reconnect is again populated:" }, +{ "send": { "type": "cache" } }, +{ "validateCache": { "isEmpty": false } }, + +{ "message": "Everything ok." } +] diff --git a/Tests/Server/tc_handshake.json b/Tests/Server/tc_handshake.json index 975bb3d..4bb7fa7 100644 --- a/Tests/Server/tc_handshake.json +++ b/Tests/Server/tc_handshake.json @@ -11,6 +11,10 @@ { "send": {"test": "sometext","cookie":"monster"} }, { "recv": {"cookie":"monster","errorMessage":"No type given in request.","inReplyTo":"","type":"error"} }, +{ "message": "Testing commands before handshake" }, +{ "send": {"type": "cache","cookie":"monster"} }, +{ "recv": {"cookie":"monster","errorMessage":"Waiting for type \"handshake\".","inReplyTo":"cache","type":"error"} }, + { "message": "Testing handshake" }, { "send": {"type": "sometype","cookie":"monster2"} }, { "recv": {"cookie":"monster2","errorMessage":"Waiting for type \"handshake\".","inReplyTo":"sometype","type":"error"} }, -- cgit v0.12