def test_StatusCmd_4(self): """ Synopsis: Issue STATUS Command/file_id,file_version. Description: Same as test_StatusCmd_3 but also File Version is specified. Expected Result: The request info for the specified file should be returned. Test Steps: See test_StatusCmd_3. Remarks: ... """ self.prepCluster((8000, 8011)) for n in range(2): sendPclCmd(port=8011).archive("src/SmallFile.fits") fileId = "TEST.2001-05-08T15:25:00.123" statObj = _execCClient( pars=[["-port", "8000"], ["-cmd", "STATUS"], ["-fileId", fileId], ["-fileVersion", "2"]])[0] self.checkTags(statObj.dumpBuf(), [ "saf/2001-05-08/2/TEST.2001-05-08T15:25:00.123.fits.gz", "TEST.2001-05-08T15:25:00.123" ])
def test_create_remote_subscriptions(self): """ Starts two servers A and B, and configures B to automatically create a subscription to A when it starts. Then, archiving a file into A should make it into B. """ subscription_pars = ( ('NgamsCfg.SubscriptionDef[1].Enable', '1'), ('NgamsCfg.SubscriptionDef[1].Subscription[1].HostId', 'localhost'), ('NgamsCfg.SubscriptionDef[1].Subscription[1].PortNo', '8888'), ('NgamsCfg.SubscriptionDef[1].Subscription[1].Command', 'QARCHIVE'), ('NgamsCfg.ArchiveHandling[1].EventHandlerPlugIn[1].Name', 'ngamsSubscriptionTest.SenderHandler')) self._prep_subscription_cluster((8888, (8889, subscription_pars))) # Listen for archives on server B (B is configured to send us notifications) listener = notification_listener() # File archived onto server A stat = sendPclCmd(port=8888).archive( 'src/SmallFile.fits', mimeType='application/octet-stream') self.assertEqual(NGAMS_SUCCESS, stat.getStatus()) with contextlib.closing(listener): self.assertIsNotNone(listener.wait_for_file(10)) # Double-check that the file is in B status = sendPclCmd(port=8889).retrieve('SmallFile.fits', targetFile='tmp') self.assertEquals(status.getStatus(), 'SUCCESS', None)
def test_RetrieveCmd_3(self): """ Synopsis: Retrieve file from NGAS Cluster sub-node. Description: Test that a file stored on a sub-node is located and returned to the requestor by the contacted server acting as proxy is Proxy Mode is eneabled. Expected Result: The contacted server should locate the file, forward the request to the node hosting the file, and should send back the file to the requestor. Test Steps: - Start simulated cluster with master and sub-node. - Archive file onto sub-node. - Submit Retrieve Request to Master Node to retrieved the archived file. - Check the response from the Master Node. - Check that the file has been retrieved as expected. Remarks: ... """ self.prepCluster((8000, 8011)) # Archive file into sub-node (port=8011). sendPclCmd(port=8011).archive("src/TinyTestFile.fits") # Retrieve a file. trgFile = "tmp/test_RetrieveCmd_3_1_tmp" client = sendPclCmd(port=8000) status = client.retrieve("NCU.2003-11-11T11:11:11.111", targetFile=trgFile) # Check reply. refStatFile = "ref/ngamsRetrieveCmdTest_test_RetrieveCmd_3_1_ref" tmpStatFile = "tmp/ngamsRetrieveCmdTest_test_RetrieveCmd_3_1_tmp" saveInFile(tmpStatFile, filterDbStatus1(status.dumpBuf(0, 1, 1))) self.checkFilesEq(refStatFile, tmpStatFile, "Incorrect status for RETRIEVE Command/Cluster " +\ "Retrieval") outFilePath = 'tmp/test_RetrieveCmd_3_1_tmp_unzip' with gzip.open(trgFile, 'rb') as gz, open(outFilePath, 'wb') as out: for data in iter(partial(gz.read, 1024), ''): out.write(data) # Check the retrieved file (checksum). refFile = "src/TinyTestFile.fits" self.checkFilesEq(outFilePath, refFile, "Retrieved file incorrect")
def test_WakeUpStatus_1(self): """ Synopsis: Test that suspended server is woken up when STATUS?host_id=<Sub-Node> specifying that node is sent. Description: If a STATUS Command is send to a node requesting status from another node (Proxy Mode), and the target is suspended, the contacted node must wake up the suspended target node. The purpose of this test is to verify this use case. Expected Result: The contacted node should identify the target node as suspended, and should wake it up prior to forwarding the STATUS Command acting as proxy. Test Steps: - Start simulated cluster specifying that one node can suspend itself. - Wait till sub-node has suspended itself. - Send STATUS Command to the simulated master requesting status from the suspended sub-node. - Check the response to the STATUS Command. - Cross check that the suspended node is now woken up by sending a STATUS Command directly to the sub-node. Remarks: ... """ cfgParDic = {"8001": [["%s.IdleSuspensionTime" % SUSP_EL, "5"]]} dbConObj = prepSimCluster(self, cfgParDic=cfgParDic)[masterNode][1] self.waitTillSuspended(dbConObj, subNode1, 30, susp_nodes) # 1. Send STATUS Command to sub-node using master as proxy. statObj = sendPclCmd(port=8000, auth=AUTH).\ get_status(NGAMS_STATUS_CMD, pars = [["host_id", subNode1]]) statBuf = filterOutLines(statObj.dumpBuf(), ["Date:", "Version:"]) tmpStatFile = saveInFile(None, statBuf) refStatFile = "ref/ngamsIdleSuspensionTest_test_WakeUpStatus_1_1_ref" refStatFile = saveInFile(None, loadFile(refStatFile) % getHostName()) self.checkFilesEq(refStatFile, tmpStatFile, "Sub-node not woken up as expected") # 2. Double-check that sub-node is no longer suspended. statObj = sendPclCmd(port=8001, auth=AUTH).status() statBuf = filterOutLines(statObj.dumpBuf(), ["Date:", "Version:"]) tmpStatFile = saveInFile(None, statBuf) self.checkFilesEq(refStatFile, tmpStatFile, "Sub-node not woken up as expected") # Clean up. self.markNodesAsUnsusp(dbConObj, susp_nodes)
def test_WakeUpRetrieve_1(self): """ Synopsis: Check that RETRIEVE?file_id and RETRIEVE?file_id&file_version are correctly handled when the file specified is stored on suspended node. Description: The test verifies that a suspended sub-node is woken up when a RETRIEVE Request is send to the Master Node and the file properly retrieved and send back to the client via the Master Node acting as proxy. Expected Result: The Master Node server should identify the target node as suspended and should wake it up before requesting the data. Subsequently the data should be send back to the client by the Master Node acting as proxy. Test Steps: - Start simulated cluster with a sub-node suspending itself after a short while. - Archive a small FITS file 3 times onto the sub-node. - Wait till the sub-node has suspended itself. - Submit a REQUEST?file_id to the Master Node. - Check that the response is as expected. - Check that the file has arrived on disk. Remarks: TODO!: Check that the file has arrived on disk as expected. """ cfgParDic = {"8001": [["%s.IdleSuspensionTime" % SUSP_EL, "5"]]} dbConObj = prepSimCluster(self, cfgParDic=cfgParDic)[masterNode][1] for n in range(3): sendPclCmd(port=8001, auth=AUTH).archive("src/SmallFile.fits") # Retrieve the file as file_id, file_id/file_version. testParsList = [["TEST.2001-05-08T15:25:00.123", -1], ["TEST.2001-05-08T15:25:00.123", 2]] for fileId, version in testParsList: self.waitTillSuspended(dbConObj, subNode1, 20, susp_nodes) # different prefixes to avoid name clashes tmpRetFile = genTmpFilename("original_") unzippedRetFile = genTmpFilename("unzip_") statObj = sendPclCmd(port=8000, auth=AUTH).\ retrieve(fileId, fileVersion=version, targetFile=tmpRetFile) self.checkEqual(NGAMS_SUCCESS, statObj.getStatus(), "Unexpected return value for RETRIEVE Command") unzip(tmpRetFile, unzippedRetFile) self.checkFilesEq("src/SmallFile.fits", unzippedRetFile, "File retrieved incorrect")
def test_DppiProc_03(self): """ Synopsis: Test the proper execution of DPPI proc./result in file/Proxy Mode. Description: When requesting a file from NGAS, it is possible to specify to have the file processed by a DPPI. The result can either be stored in a file or contained in the buffer when handed over to the NG/AMS Server. Expected Result: The DPPI should be invoked the file to be retrieved and the result (stored by the DPPI in a file), properly sent back to the client. This is tested while retrieving the DPPI processed via a server acting as proxy. Test Steps: - Start a simulated cluster. - Archive a file into sub-node. - Retrieve the file via the master, specifying to apply the DPPI on it. - Check that the file has been processed as expected. Remarks: ... Test Data: ... """ ncuCfgPars = [[ "NgamsCfg.Processing[1].PlugIn[1].Name", "ngamsTest.ngamsTestDppi1" ], [ "NgamsCfg.Processing[1].PlugIn[1].PlugInPars", "TAG=test_DppiProc_02,TARGET=FILE" ]] self.prepCluster((8000, (8011, ncuCfgPars))) stat = sendPclCmd(port=8011).archive("src/SmallFile.fits") self.assertEquals('SUCCESS', stat.getStatus()) # Retrieve the file specifying to apply the DPPI. outFile = genTmpFilename("test_DppiProc_03") pars = [["test_suite", "ngamsRetrieveCmdTest"], ["test_case", "test_DppiProc_03"]] stat = sendPclCmd(port=8000).retrieve( "TEST.2001-05-08T15:25:00.123", targetFile=outFile, processing="ngamsTest.ngamsTestDppi1", pars=pars) refStatFile = "ref/ngamsRemFileCmdTest_test_DppiProc_03_01_ref" self.checkFilesEq(refStatFile, outFile, "Incorrect status for " +\ "RETRIEVE Command/DPPI Processing, Proxy Mode, " +\ "result in buffer")
def test_ProxyMode_01(self): """ Synopsis: Test that the proxy mode works for the CHECKFILE Command/cluster. Description: The purpose of the test is to verify that the proxy mode works properly for the CHECKFILE Command. In practice, this means that if a file to be check is stored on another NGAS Node than the contacted one, the contacted node (acting as cluster master) should locate the file and forward the request to the node hosting the file. Expected Result: When issuing the CHECKFILE Command to the cluster master node, it should figure out that the file specified is stored on a sub-node. The master node will forward the request to the sub-node, which will carry out the check and return the response, which is then forwarded to the client. Test Steps: - Start simulated cluster with 1 MNU + 1 NCU. - Archive file onto the NCU. - Archive file onto the NMU. - Issue a CHECKFILE Command to the NMU specifying the file on the NCU. - Verify that the proper file has been checked. Remarks: ... Test Data: ... """ self.prepCluster((8000, 8011)) sendPclCmd(port=8000).archive("src/SmallFile.fits") stat = sendPclCmd(port=8011).archive("src/SmallFile.fits") diskId = "tmp-ngamsTest-NGAS:8011-FitsStorage1-Main-1" fileId = "TEST.2001-05-08T15:25:00.123" fileVer = 2 httpPars = [["disk_id", diskId], ["file_id", fileId], ["file_version", fileVer]] tmpStatFile = sendExtCmd(8000, NGAMS_CHECKFILE_CMD, pars=httpPars, replaceLocalHost=1) refStatFile = "ref/ngamsCheckFileCmdTest_test_ProxyMode_01_01_ref" self.checkFilesEq(refStatFile, tmpStatFile, "Incorrect handling of "+\ "CHECKFILE Command detected")
def test_ProxyMode_01(self): """ Synopsis: Test that the proxy mode is not possible for the REMFILE Command. Description: It is not possible to let a contacted NGAS Node act as proxy for the REMFILE Command (for security reasons). I.e., the node where data should be removed, must be contacted directly/explicitly. Expected Result: When issuing the REMFILE Command to the cluster master node, it should figure out that the file specified is stored on a sub-node and the request should be rejected. Test Steps: - Start simulated cluster with 1 MNU + 1 NCU. - Archive file onto the NMU. - Archive file onto the NCU. - Clone file onto another within the NCU. - Issue a REMFILE Command to the NMU specifying the file on the NCU (execute=0). - Verify that the mistake is detected and the request rejected. - Issue a REMFILE Command to the NMU specifying the file on the NCU (execute=1). - Verify that the mistake is detected and the request rejected. Remarks: ... Test Data: ... """ self.prepCluster((8000, 8011)) sendPclCmd(port=8000).archive("src/SmallFile.fits") client8011 = sendPclCmd(port=8011) stat = client8011.archive("src/SmallFile.fits") diskId = "tmp-ngamsTest-NGAS:8011-FitsStorage1-Main-1" fileId = "TEST.2001-05-08T15:25:00.123" fileVer = 2 client8011.clone(fileId, diskId, fileVer) for execute in [0, 1]: httpPars = [["disk_id", diskId], ["file_id", fileId], ["file_version", fileVer], ["execute", execute]] tmpStatFile = sendExtCmd(8000, NGAMS_REMFILE_CMD, pars=httpPars) refStatFile = "ref/ngamsRemFileCmdTest_test_ProxyMode_01_01_ref" self.checkFilesEq( refStatFile, tmpStatFile, "Incorrect handling of REMFILE Command detected")
def test_HttpRedirection_01(self): """ Synopsis: Test the HTTP redirection, contacted node redirects to sub-node. Description: The purpose of this test case is to verify that the HTTP redirection works in connection with the RETRIEVE Command. Expected Result: The contacted node should detect that the file requested is stored on another node (sub-node). It should resolve the address and return an HTTP re-direction response to the client Python-API, which internally will pick up the file. Test Steps: - Start simulated cluster (Proxy Mode: Off). - Archive file onto MNU, archive file onto NCU. - Submit RETRIEVE to retrieve file on NCU. - Check that an HTTP redirection response was returned such that the file was retrieved directly from the sub-node. Remarks: ... Test Data: ... """ nmuCfgPars = [["NgamsCfg.Server[1].ProxyMode", "0"], ["NgamsCfg.Log[1].LocalLogLevel", "4"]] self.prepCluster(((8000, nmuCfgPars), 8011)) self.assertStatus(sendPclCmd(port=8000).archive("src/SmallFile.fits")) self.assertStatus(sendPclCmd(port=8011).archive("src/SmallFile.fits")) # The ngamsPClient handles redirects automatically, # but we want to manually check here that things are right fileId = "TEST.2001-05-08T15:25:00.123" pars = (("file_id", fileId), ) resp = ngamsHttpUtils.httpGet('127.0.0.1', 8000, 'RETRIEVE', pars=pars) self.assertEqual(303, resp.status) resp.close() # Follow the Location, we should get it now host, port = resp.getheader('Location').split('/')[2].split(':') port = int(port) resp = ngamsHttpUtils.httpGet(host, port, 'RETRIEVE', pars=pars) self.assertEqual(200, resp.status) resp.close()
def test_StatusCmd_2(self): """ Synopsis: Test normal execution of STATUS Command/Proxy. Description: If another node is specified than the contacted node, when submitting the STATUS Command, the contacted node should act as proxy and should forward the request to the specified sub-node. Expected Result: The response from the specified sub-node should be returned to the client. Test Steps: - Start simulated cluster. - Submit STATUS Command referring to sub-node in cluster. - Check that the response returned indicates that the request was forwarded to the sub-node. Remarks: ... """ self.prepCluster((8000, 8011)) statObj = sendPclCmd(port=8000).\ get_status("STATUS", pars=[["host_id", getNcu11()]]) refMsg = "Successfully handled command STATUS" if ((statObj.getMessage().find(refMsg) == -1) or (statObj.getHostId() != getNcu11())): self.fail("Illegal status returned for STATUS Command")
def test_ExitCmd_2(self): """ Synopsis: Server in Online State -> EXIT Command rejected. Description: Test that the EXIT Command is rejected when submitted when the server is in Online State. Expected Result: The server should generate an Error Response indicating that the command cannot be handled when the server is in Online State. Test Steps: - Start server (Auto Online = 1). - Issue EXIT Command. - Check that the request is rejected. - Check that the server is still running. Remarks: TODO!: Check that the server is still running after the EXIT Command. """ self.prepExtSrv(autoOnline=1) client = sendPclCmd(timeOut=10) stat = client.exit() self.assertEquals(ngamsCore.NGAMS_FAILURE, stat.getStatus()) self.assertEquals(4015, int(stat.getMessage().split(":")[1])) # NGAMS_ER_IMPROPER_STATE # The server is still running stat = client.status() self.assertEquals(ngamsCore.NGAMS_SUCCESS, stat.getStatus())
def test_ExitCmd_1(self): """ Synopsis: Normal execution EXIT Command/Offline. Description: Test that the server terminates if the EXIT Command is submitted while the server is in Offline State. Expected Result: The server in Offline State, should accept the EXIT Command and perform a clean shut down. Test Steps: - Start server (Auto Online = 0). - Submit EXIT Command. - Check that the response is as expected. - Check that the server is no longer running. Remarks: TODO!: Test that the server is no longer running. """ self.prepExtSrv(autoOnline=0) client = sendPclCmd(timeOut=10) stat = client.exit() self.assertEquals(ngamsCore.NGAMS_SUCCESS, stat.getStatus())
def test_url_values(self): self.prepExtSrv() client = sendPclCmd() # empty url status = client.subscribe(' ') self.assertEqual('FAILURE', status.getStatus()) self.assertIn('empty', status.getMessage()) # Missing scheme status = client.subscribe('some/path') self.assertEqual('FAILURE', status.getStatus()) self.assertIn('no scheme found', status.getMessage().lower()) # Missing network location # These are all interpreted as <scheme>:<path>, # even if it looks like a network location to the eye for url in ('scheme:some/path', 'host:80/path', 'file:///tmp/file'): status = client.subscribe(url) self.assertEqual('FAILURE', status.getStatus()) self.assertIn('no netloc found', status.getMessage().lower()) # Scheme is actually not http for url in ( "ftp://host:port/path", # ftp scheme not allowed "https://host/path", # https not allowed "file://hostname:port/somewhere/over/the/rainbow" # file not allowed ): status = client.subscribe(url) self.assertEqual('FAILURE', status.getStatus()) self.assertIn('only http:// scheme allowed', status.getMessage().lower())
def archiveThread(testObj, no, inc, dummy): """ Archive a file X times. testObj: Reference to instance of ngamsTestSuite object (ngamsTestSuite). no: Number allocated to thread (integer). inc: Increment ARCFILE keyword before submitting each Archive Request (0|1/integer). Returns: Void """ if (inc): filename = "tmp/ngamsArchiveStressTest_%d.fits" % no cpFile("src/TinyTestFile.fits", filename) incArcfile(filename, step=(100 * no)) else: filename = "src/TinyTestFile.fits" testStr = TST_STR1 % os.path.basename(filename) for n in range(5): if (not RUN_TEST): THREAD_STAT[no] = "STOPPED" break if (inc): incArcfile(filename) statObj = sendPclCmd(auth=AUTH).archive(filename) if (statObj.getMessage() != testStr): THREAD_STAT[no] = "FAILURE: Archive Request failed" THREAD_STAT[no] = "SUCCESS" thread.exit()
def test_StressTest_1(self): """ Synopsis: Archive a small file 20 times, sequentially Description: The Test Case execises the situation where a (small) FITS file is archived sequentially for a certain number of times. Expected Result: All N Archive Requests should be handled successfully. Test Steps: - Start server. - Issue a small FITS file N times, check that a response is returned indicating a successfull execution. Remarks: To make this test useful, it would be better to archive a much higher quantity of files to test also the stability of handling 1000s requests over a long period of time. """ testStr = TST_STR1 % "TinyTestFile.fits" self.prepExtSrv() for n in range(20): statObj = sendPclCmd(auth=AUTH).archive("src/TinyTestFile.fits") self.checkEqual(statObj.getMessage(), testStr, "Archive Request failed")
def _test_data_check_thread(self, registered, unregistered, bad, corrupt=None): # Start the server normally without the datacheck thread # and perform some archives. Turn off snapshoting also, # it messes up with the database updates in one of the tests _, db = self.prepExtSrv(cfgProps=(("NgamsCfg.Db[1].Snapshot", "0"), )) client = sendPclCmd() for _ in range(3): client.archive("src/SmallFile.fits") # Cleanly shut down the server, and wait until it's completely down old_cleanup = getNoCleanUp() setNoCleanUp(True) self.termExtSrv(self.extSrvInfo.pop()) setNoCleanUp(old_cleanup) # Potentially corrupt the NGAS data somehow if corrupt: corrupt(db) # Restart and see what does the data checker thread find cfg, db = self.start_srv(delDirs=0, clearDb=0) self.wait_and_count_checked_files(cfg, db, registered, unregistered, bad)
def test_StatusCmd_1(self): """ Synopsis: Test normal execution of STATUS Command/local. Description: Test the execution of the STATUS Command when no parameters are specified. This just makes the server return the basic status about the operational environment. Expected Result: The server should return a reponse to the STATUS Command, indicating the status of the system. Test Steps: - Start server. - Submit STATUS Command. - Check that the response to the STATUS Command contains the info as expected. Remarks: ... """ self.prepExtSrv() client = sendPclCmd(port=8888) status = client.status() if (status.getMessage().\ find("Successfully handled command STATUS") == -1): self.fail("Illegal status returned for STATUS Command")
def test_DbSnapshot_6(self): """ Synopsis: Test that DB Snapshot is updated correctly when file are registered. Description: The purpose of the test is to verify that the DB Snapshot of a disk on which files are being registered, is properly updated according to the files registered. Expected Result: After a short while, the information for the files registered should appear in the DB Snapshot of the disk. Test Steps: - Start server. - Copy over a small test FITS file in 3 copies. - Send a REGISTER Command to register the files copied over (specifying root directory of the files). - Check that the DB Snapshot is updated within a given period of time. Remarks: ... """ cfgObj, dbObj = _prepSrv(self) client = sendPclCmd() regTestDir = "/tmp/ngamsTest/NGAS/FitsStorage1-Main-1/reg_test" checkCreatePath(regTestDir) for n in range(3): cpFile('src/SmallFile.fits', os.path.join(regTestDir, "%d.fits" % n)) client.get_status(NGAMS_REGISTER_CMD, pars = [["path", regTestDir]]) _checkContDbSnapshot(self, 6, ["FitsStorage1-Main-1"], 1, 1)
def test_ServerLoad_1(self): """ Synopsis: Test that the NG/AMS Server is loading configuration from DB and initializing as expected. Description: Test that the NG/AMS Server can load the configuration properly from the DB and initialize accordingly. Expected Result: The server should load the DB parameters according the specified NGAS Configuration ID specified and should start up properly. Test Steps: - Load the configuration into the DB. - Start an NG/AMS Server specifying an XML document which only defines the DB connection + giving the reference to the DB Cfg. ID. - Verify that the NG/AMS Server starts up properly. Remarks: ... """ cfgName = "test_ServerLoad_1" cfgObj, _ = self.loadCfg(cfgName) cfgFile = saveInFile(None, str(cfgObj.genXmlDoc())) self.prepExtSrv(cfgFile=cfgFile, dbCfgName=cfgName, clearDb=0) # Archive a file, should be OK. statObj = sendPclCmd().archive("src/SmallFile.fits") refStatFile = "ref/ngamsConfigHandlingTest_test_ServerLoad_1_1_ref" tmpStatFile = saveInFile(None, filterDbStatus1(statObj.dumpBuf())) self.checkFilesEq(refStatFile, tmpStatFile, "Incorrect status " +\ "returned for Archive Push Request")
def test_ChangeLocLogLev_1(self): """ Synopsis: Change the Local (Log File) Log Level Online. Description: The purpose of this Test Case is to test that the Local Log Level can be changed while the NG/AMS Server is Online. Expected Result: The Log Level should be increased and more logs produced in the Local Log File. Test Steps: - Start normal NG/AMS Server (Log Level=3). - Send a CONFIG Command to the server changing the Log Level to 4. - Check the response to the CONFIG Command is correct. Remarks: TODO: Check in Log File that low level logs are produced. """ self.prepExtSrv() statObj = sendPclCmd().get_status(NGAMS_CONFIG_CMD, pars=[["log_local_log_level", "4"]]) tmpStatFile = "tmp/ngamsConfigCmdTest_test_ChangeLocLogLev_1_1_tmp" refStatFile = "ref/ngamsConfigCmdTest_test_ChangeLocLogLev_1_1_ref" saveInFile( tmpStatFile, filterOutLines(statObj.dumpBuf(), ["Date", "Version", "HostId"])) self.checkFilesEq(refStatFile, tmpStatFile, "Incorrect info in " +\ "CONFIG Command XML Status " + "Document/log_local_log_level")
def test_DbSnapshot_5(self): """ Synopsis: Test that DB Snapshot is updated correctly when files are cloned. Description: The purpose of the test is to verify that the DB Snapshot on a disk, is updated (on-the-fly) when files are being cloned onto it. Expected Result: A short time after the files have been cloned onto a given disk, the information about the files should appear in the DB Snapshot of the disk. Test Steps: - Start server. - Archive a small test FITS file 3 times. - Clone the Main Disk hosting the 3 files archived. - Check that the DB Snapshot of the Target Disk has been updated with the information about the files cloned. Remarks: ... """ cfgObj, dbObj = _prepSrv(self) client = sendPclCmd() for n in range(3): client.archive("src/SmallFile.fits") diskId = "tmp-ngamsTest-NGAS-FitsStorage1-Main-1" client.get_status(NGAMS_CLONE_CMD, pars = [["disk_id", diskId]]) time.sleep(5) _checkContDbSnapshot(self, 5, ["FitsStorage2-Main-3"])
def test_DbSnapshot_4(self): """ Synopsis: DB Snapshot is updated correctly when a disk is removed (REMDISK'ed). Description: The purpose of this test is to verify that the DB Snapshot of a disk is correctly updated when the files contained and registered on the disks are removed via a REMDISK Command. Expected Result: A while after executing the REMDISK Command, the corresponding entries should disappear from the DB Snapshot of the REMDISK'ed disk. Test Steps: - Start a server. - Archive a small FITS file 3 times. - Clone the disk. - Remove the resulting, cloned disk. - Check that within a short time-out, all entries from the DB Snapshot disappears. Remarks: ... """ cfgObj, dbObj = _prepSrv(self) client = sendPclCmd() for n in range(3): client.archive("src/SmallFile.fits") diskId = "tmp-ngamsTest-NGAS-FitsStorage1-Main-1" client.get_status(NGAMS_CLONE_CMD, pars = [["disk_id", diskId]]) client.get_status(NGAMS_REMDISK_CMD, pars = [["disk_id", diskId], ["execute", "1"]]) time.sleep(1) _checkContDbSnapshot(self, 4, ["FitsStorage1-Main-1"])
def test_DbSnapshot_2(self): """ Synopsis: Test that DB Snapshot is updated when files are archived. Description: The purpose of this test is to verify that the DB Snapshot is updated 'real-time' when files are archived onto a disk. Expected Result: After having archived 3 files, the Janitor Thread should be triggered to update the DB Snapshot. Test Steps: - Prepare instance of NG/AMS Server. - Archive a small FITS file 3 times. - Wait till the Temporary File Snapshots have been handled by the Janitor Thread. - Check that the DB Snapshot has been updated accordingly. Remarks: ... """ cfgObj, dbObj = _prepSrv(self) client = sendPclCmd() for n in range(3): client.archive("src/SmallFile.fits") _checkContDbSnapshot(self, 2, ["FitsStorage1-Main-1", "FitsStorage1-Rep-2"])
def test_files_list(self): self.prepExtSrv() client = sendPclCmd() # No files archived, there was an error on the previous implementation stat = client.get_status("QUERY", pars=[['query', 'files_list'], ['format', 'list']]) self.assertStatus(stat) # One file archived, let's see what happens now stat = client.archive("src/SmallFile.fits") self.assertStatus(stat) stat = client.get_status("QUERY", pars=[['query', 'files_list'], ['format', 'list']]) self.assertStatus(stat) # Make sure that the other formats work as well stat = client.get_status("QUERY", pars=[['query', 'files_list'], ['format', 'text']]) self.assertStatus(stat) stat = client.get_status("QUERY", pars=[['query', 'files_list'], ['format', 'json']]) self.assertStatus(stat) stat = client.get_status("QUERY", pars=[['query', 'files_list']]) self.assertStatus(stat) # Check that the archived file is listed data = stat.getData() self.assertTrue("TEST.2001-05-08T15:25:00.123" in data)
def test_NormalExec_1(self): """ Synopsis: File existing execute=0,1/Disk ID/File ID/File Version. Description: The purpose of the test is to verify that the normal functioning of the DISCARD Command when it is tried to DISCARD a file referred to by its corresponding Disk ID, File ID and File Version. Expected Result: The server should find the file, and should return a positive response when issuing the DISCARD Command with execute=0. Subsequently, when submitting the command with execute=1, the file should disappear from the NGAS DB and from the disk. Test Steps: - Start NG/AMS Server. - Archive a file. - Issue a DISCARD Command specifying the Disk ID/File ID/File Version of the file/execute=0. - Check that the response from the NG/AMS Server reports that only one copy is available of the file. - Issue a DISCARD Command specifying the Disk ID/File ID/File Version of the file/execute=1. - Check that the response from the NG/AMS Server reports that the file was DISCARDED. Remarks: ... """ self.prepExtSrv() sendPclCmd().archive(srcFitsFile) mDiskId = "tmp-ngamsTest-NGAS-FitsStorage1-Main-1" pars = [["disk_id", mDiskId], ["file_id", "TEST.2001-05-08T15:25:00.123"], ["file_version", "1"]] tmpStatFile = sendExtCmd(8888, NGAMS_DISCARD_CMD, pars + [["execute", "0"]]) refStatFile = "ref/ngamsDiscardCmdTest_test_NormalExec_1_1_ref" self.checkFilesEq(refStatFile, tmpStatFile, illStatDoc % "1") # TODO!: Check that file info is not removed from the DB # TODO!: Check that file is not removed from the disk refStatFile = "ref/ngamsDiscardCmdTest_test_NormalExec_1_2_ref" tmpStatFile = sendExtCmd(8888, NGAMS_DISCARD_CMD, pars + [["execute", "1"]]) self.checkFilesEq(refStatFile, tmpStatFile, illStatDoc % "2")
def test_NormalExec_3(self): """ Synopsis: File existing/3 copies execute=0,1/Disk ID/File ID/File Version. Description: The purpose of the test is to verify that the normal functioning of the DISCARD Command when it is tried to DISCARD a file referred to by its corresponding Disk ID, File ID and File Version. The file is available in three copies. Expected Result: The server should find the file, and should return a positive response when issuing the DISCARD Command with execute=0. Subsequently, when submitting the command with execute=1, the file should disappear from the NGAS DB and from the disk. Test Steps: - Start NG/AMS Server. - Archive a file. - Clone the file onto another disk. - Issue a DISCARD Command specifying the Disk ID/File ID/File Version of the file/execute=0. - Check that the response from the NG/AMS Server reports that only one copy is available of the file. - Issue a DISCARD Command specifying the Disk ID/File ID/File Version of the file/execute=1. - Check that the response from the NG/AMS Server reports that the file was DISCARDED. Remarks: ... """ self.prepExtSrv() sendPclCmd().archive("src/SmallFile.fits") mDiskId = "tmp-ngamsTest-NGAS-FitsStorage1-Main-1" fileId = "TEST.2001-05-08T15:25:00.123" sendPclCmd().clone(fileId, mDiskId, 1) for execute in [0, 1]: httpPars = [["disk_id", mDiskId], ["file_id", fileId], ["file_version", "1"], ["execute", execute]] tmpStatFile = sendExtCmd(8888, NGAMS_DISCARD_CMD, pars=httpPars) refStatFile = "ref/ngamsDiscardCmdTest_test_NormalExec_3_%d_ref"%\ (execute + 1) self.checkFilesEq(refStatFile, tmpStatFile, "Unexpected result "+\ "of DISCARD Command (execute=%d)" % execute)
def test_cache_delete(self): self.prepExtSrv(cache=True) r = sendPclCmd().archive('src/SmallFile.fits') self.assertEquals(r.getStatus(), 'SUCCESS', None) status = delete_ngas_file('localhost', 8888, 'TEST.2001-05-08T15:25:00.123', 1, r.getDiskStatusList()[0].getDiskId()) self.assertEquals(status, 200, None)
def test_too_many_requests(self): saveInFile("tmp/handleHttpRequest_tmp", "handleHttpRequest_Block5secs") self.prepExtSrv(srvModule="ngamsSrvTestDynReqCallBack", cfgProps=(('NgamsCfg.Server[1].MaxSimReqs', '2'), )) # Fire off two clients, each takes 5 seconds to finish cl1, cl2 = sendPclCmd(), sendPclCmd() threading.Thread(target=cl1.online).start() threading.Thread(target=cl2.online).start() # The third one should not pass through # (assuming that 2 seconds were enough for the two clients # to connect and be busy waiting for their reply) time.sleep(2) resp = ngamsHttpUtils.httpGet('127.0.0.1', 8888, 'ONLINE') with contextlib.closing(resp): self.assertEqual(NGAMS_HTTP_SERVICE_NA, resp.status)
def test_RemDiskCmd_1(self): """ Synopsis: Normal execution. Description: Test the normal execution of the REMDISK Command, where a disk, containing files with at least 3 independent copies is request REMDISK'ed. Expected Result: When executing the REMDISK Command on the cloned disk with execute=0, the server should accept the command and report this to the client. When re-issuing the REMDISK Command on the cloned disk with execute=1, the server should accept the command, execute the REMDISK procedure on the disk and report this to the client. Test Steps: - Start server. - Archive a file. - Clone the disk hosting the archived file. - Issue REMDISK Command to remove the cloned disk (execute=0). - Check response from the server. - Issue REMDISK Command to remove the cloned disk (execute=1). - Check response from the server. Remarks: TODO!: It is not checked that the contents on the disk and the info in the DB in ngas_files and ngas_disks is properly updated. """ self.prepExtSrv(cfgProps=(('NgamsCfg.Server[1].RequestDbBackend', 'memory'),)) client = sendPclCmd() # Archive a file + clone it to be able to execute the REMDISK Command. diskId = "tmp-ngamsTest-NGAS-FitsStorage1-Main-1" client.archive("src/SmallFile.fits") status = client.clone("", diskId, -1) waitReqCompl(client, status.getRequestId()) # Remove the cloned disk (execute=0), should be successfull. status = client.remDisk(diskId, 0) refStatFile = "ref/ngamsRemDiskCmdTest_test_RemDiskDisk_1_1_ref" tmpStatFile = "tmp/ngamsRemDiskCmdTest_test_RemDiskDisk_1_1_tmp" saveInFile(tmpStatFile, filterDbStatus1(status.dumpBuf(0, 1, 1))) self.checkFilesEq(refStatFile, tmpStatFile, "Incorrect status for REMDISK Command/no execution") # Remove the cloned disk (execute=1), should be successfull. status = client.remDisk(diskId, 1) refStatFile = "ref/ngamsRemDiskCmdTest_test_RemDiskDisk_1_2_ref" tmpStatFile = "tmp/ngamsRemDiskCmdTest_test_RemDiskDisk_1_2_tmp" saveInFile(tmpStatFile, filterDbStatus1(status.dumpBuf(0, 1, 1))) self.checkFilesEq(refStatFile, tmpStatFile, "Incorrect status for REMDISK Command/execution")
def test_ServerLoad_3(self): """ Synopsis: Test loading of specific configuration from DB. Description: Test that the NG/AMS Server is loading configuration from DB and initializing as expected without mixing up parameters from other configurations in the DB. Expected Result: The NG/AMS Server should load only parameters for the specified configuration Group ID and ignore other parameters in the DB. Test Steps: - Prepare two XML configurations and load them in the DB. Difference is that all attribute values of the second are set to value=0, which means that the server could not operate if mixing up parameters from the two. - Start server. - Archive file and check that the file was successfully archived. Remarks: ... """ cfgName1 = "test_ServerLoad_1" cfgObj, _ = self.loadCfg(cfgName1) cfgFile = saveInFile(None, cfgObj.genXmlDoc(0)) # For the second cfg. set all the DB Cfg. Group ID to a common value # + set all values to a non-sense value. cfgName2 = "test_ServerLoad_2" tmpCfg = db_aware_cfg("src/ngamsCfg.xml") for cfgKey in tmpCfg._getXmlDic().keys(): if ((cfgKey[-1] != "]") and (cfgKey.find("Db[1]") == -1)): tmpCfg.storeVal(cfgKey, "0") tmpCfg.storeVal("NgamsCfg.Log[1].LocalLogFile", "/tmp/ngamsTest/NGAS/log/LogFile.nglog", "0") tmpCfgFile = saveInFile(None, tmpCfg.genXmlDoc(0)) self.loadCfg(cfgName2, cfgFile=tmpCfgFile, checkCfg=0, delDbTbls=0, dbCfgGroupIds=[0], createDatabase=False) # Start server specifying 1st DB cfg. self.prepExtSrv(cfgFile=cfgFile, dbCfgName=cfgName1, clearDb=0) statObj = sendPclCmd().archive("src/SmallFile.fits") refStatFile = "ref/ngamsConfigHandlingTest_test_ServerLoad_3_1_ref" tmpStatFile = saveInFile(None, filterDbStatus1(statObj.dumpBuf())) self.checkFilesEq(refStatFile, tmpStatFile, "Incorrect status " +\ "returned for Archive Push Request")