Commit 13e60cca by Gabe Mulley

Acceptance test for export of courseware_studentmodule

Provide coverage for the integration of an externally generated courseware_studentmodule in to the research data exports.

Change-Id: I32e3fbf5928581581babb1502fd17a590cbaf960
parent f073aabb
...@@ -19,7 +19,11 @@ test-requirements: requirements ...@@ -19,7 +19,11 @@ test-requirements: requirements
test: test-requirements test: test-requirements
# TODO: when we have better coverage, modify this to actually fail when coverage is too low. # TODO: when we have better coverage, modify this to actually fail when coverage is too low.
rm -rf .coverage rm -rf .coverage
python -m coverage run --rcfile=./.coveragerc `which nosetests` python -m coverage run --rcfile=./.coveragerc `which nosetests` -A 'not acceptance'
test-acceptance: test-requirements
rm -rf .coverage
python -m coverage run --rcfile=./.coveragerc `which nosetests` --nocapture -A acceptance
coverage: test coverage: test
coverage html coverage html
...@@ -38,3 +42,26 @@ jenkins: .tox ...@@ -38,3 +42,26 @@ jenkins: .tox
virtualenv ./venv virtualenv ./venv
./venv/bin/pip install tox ./venv/bin/pip install tox
./venv/bin/tox ./venv/bin/tox
get_config = $(shell echo "$$ACCEPTANCE_TEST_CONFIG" | python -c 'import sys, json; print json.load(sys.stdin)[sys.argv[1]]' $(1))
VENV_ROOT = $(shell echo "$$WORKSPACE/build/venvs")
META_BIN = $(VENV_ROOT)/meta/bin
EXPORTER_BIN = $(VENV_ROOT)/analytics-exporter/bin
export EXPORTER=$(EXPORTER_BIN)/exporter
TASKS_BIN = $(VENV_ROOT)/analytics-tasks/bin
export REMOTE_TASK=$(TASKS_BIN)/remote-task
jenkins-acceptance:
mkdir -p $(VENV_ROOT)
virtualenv $(VENV_ROOT)/analytics-tasks
virtualenv $(VENV_ROOT)/analytics-exporter
virtualenv $(VENV_ROOT)/meta
$(META_BIN)/pip install awscli
$(META_BIN)/aws s3 rm --recursive $(call get_config,tasks_output_url)$(call get_config,identifier) || true
$(EXPORTER_BIN)/pip install -r $$WORKSPACE/analytics-exporter/requirements.txt
$(EXPORTER_BIN)/pip install -e $$WORKSPACE/analytics-exporter/
. $(TASKS_BIN)/activate && $(MAKE) test-acceptance
-- MySQL dump 10.13 Distrib 5.5.32, for debian-linux-gnu (x86_64)
--
-- Host: stage-edx.rds.edx.org Database: wwc
-- ------------------------------------------------------
-- Server version 5.1.63-log
--
-- Table structure for table `courseware_studentmodule`
--
DROP TABLE IF EXISTS `courseware_studentmodule`;
CREATE TABLE `courseware_studentmodule` (`id` int(11) NOT NULL AUTO_INCREMENT, `module_type` varchar(32) NOT NULL DEFAULT 'problem', `module_id` varchar(255) NOT NULL, `student_id` int(11) NOT NULL, `state` longtext, `grade` double DEFAULT NULL, `created` datetime NOT NULL, `modified` datetime NOT NULL, `max_grade` double, `done` varchar(8) NOT NULL, `course_id` varchar(255) NOT NULL, PRIMARY KEY (`id`), UNIQUE KEY `courseware_studentmodule_student_id_635d77aea1256de5_uniq` (`student_id`,`module_id`,`course_id`), KEY `courseware_studentmodule_42ff452e` (`student_id`), KEY `courseware_studentmodule_3216ff68` (`created`), KEY `courseware_studentmodule_6dff86b5` (`grade`), KEY `courseware_studentmodule_5436e97a` (`modified`), KEY `courseware_studentmodule_2d8768ff` (`module_type`), KEY `courseware_studentmodule_f53ed95e` (`module_id`), KEY `courseware_studentmodule_1923c03f` (`done`), KEY `courseware_studentmodule_ff48d8e5` (`course_id`)) ENGINE=InnoDB AUTO_INCREMENT=97209 DEFAULT CHARSET=utf8;
--
-- Dumping data for table `courseware_studentmodule`
--
-- WHERE: course_id="edX/E929/2014_T1"
INSERT INTO `courseware_studentmodule` VALUES (96112,'course','i4x://edX/E929/course/2014_T1',1091,'{\"position\": 5}',NULL,'2014-03-04 14:28:27','2014-04-11 18:50:52',NULL,'na','edX/E929/2014_T1'),(96113,'chapter','i4x://edX/E929/chapter/d8a6192ade314473a78242dfeedfbf5b',1091,'{\"position\": 1}',NULL,'2014-03-04 14:28:27','2014-03-04 14:28:27',NULL,'na','edX/E929/2014_T1'),(96114,'sequential','i4x://edX/E929/sequential/edx_introduction',1091,'{\"position\": 1}',NULL,'2014-03-04 14:28:28','2014-03-04 14:28:28',NULL,'na','edX/E929/2014_T1'),(96115,'chapter','i4x://edX/E929/chapter/interactive_demonstrations',1091,'{\"position\": 2}',NULL,'2014-03-04 14:28:34','2014-03-04 14:28:34',NULL,'na','edX/E929/2014_T1'),(96116,'problem','i4x://edX/E929/problem/c554538a57664fac80783b99d9d6da7c',1091,'{\"correct_map\": {\"i4x-edX-E929-problem-c554538a57664fac80783b99d9d6da7c_2_1\": {\"hint\": \"\", \"hintmode\": null, \"correctness\": \"correct\", \"msg\": \"\", \"npoints\": null, \"queuestate\": null}}, \"input_state\": {\"i4x-edX-E929-problem-c554538a57664fac80783b99d9d6da7c_2_1\": {}}, \"attempts\": 1, \"seed\": 1, \"done\": true, \"student_answers\": {\"i4x-edX-E929-problem-c554538a57664fac80783b99d9d6da7c_2_1\": \"[482,173]\"}}',1,'2014-03-04 14:28:34','2014-04-11 18:47:43',1,'na','edX/E929/2014_T1'),(96117,'problem','i4x://edX/E929/problem/d2e35c1d294b4ba0b3b1048615605d2a',1091,'{\"correct_map\": {\"i4x-edX-E929-problem-d2e35c1d294b4ba0b3b1048615605d2a_2_1\": {\"hint\": \"\", \"hintmode\": null, \"correctness\": \"incorrect\", \"npoints\": 0, \"msg\": \"\", \"queuestate\": null}}, \"input_state\": {\"i4x-edX-E929-problem-d2e35c1d294b4ba0b3b1048615605d2a_2_1\": {}}, \"attempts\": 1, \"seed\": 1, \"done\": true, \"student_answers\": {\"i4x-edX-E929-problem-d2e35c1d294b4ba0b3b1048615605d2a_2_1\": \"[{\\\"1\\\":[155.5,147]},{\\\"2\\\":[244.5,146]},{\\\"3\\\":[66.5,169]},{\\\"4\\\":[281.5,146]},{\\\"5\\\":[78.5,191]},{\\\"6\\\":[306.5,171]},{\\\"7\\\":[536.5,150]},{\\\"8\\\":[420.5,170]},{\\\"9\\\":[201.5,181]},{\\\"10\\\":[408.5,164]}]\"}}',0,'2014-03-04 14:28:34','2014-04-11 18:47:35',1,'na','edX/E929/2014_T1'),(96118,'problem','i4x://edX/E929/problem/a0effb954cca4759994f1ac9e9434bf4',1091,'{\"correct_map\": {\"i4x-edX-E929-problem-a0effb954cca4759994f1ac9e9434bf4_4_1\": {\"hint\": \"\", \"hintmode\": null, \"correctness\": \"incorrect\", \"npoints\": null, \"msg\": \"\", \"queuestate\": null}, \"i4x-edX-E929-problem-a0effb954cca4759994f1ac9e9434bf4_3_1\": {\"hint\": \"\", \"hintmode\": null, \"correctness\": \"incorrect\", \"npoints\": null, \"msg\": \"\", \"queuestate\": null}, \"i4x-edX-E929-problem-a0effb954cca4759994f1ac9e9434bf4_2_1\": {\"hint\": \"\", \"hintmode\": null, \"correctness\": \"correct\", \"npoints\": null, \"msg\": \"\", \"queuestate\": null}}, \"input_state\": {\"i4x-edX-E929-problem-a0effb954cca4759994f1ac9e9434bf4_4_1\": {}, \"i4x-edX-E929-problem-a0effb954cca4759994f1ac9e9434bf4_3_1\": {}, \"i4x-edX-E929-problem-a0effb954cca4759994f1ac9e9434bf4_2_1\": {}}, \"attempts\": 1, \"seed\": 1, \"done\": true, \"student_answers\": {\"i4x-edX-E929-problem-a0effb954cca4759994f1ac9e9434bf4_4_1\": [\"choice_1\", \"choice_2\", \"choice_3\"], \"i4x-edX-E929-problem-a0effb954cca4759994f1ac9e9434bf4_3_1\": \"choice_0\", \"i4x-edX-E929-problem-a0effb954cca4759994f1ac9e9434bf4_2_1\": \"blue\"}}',1,'2014-03-04 14:28:34','2014-04-11 18:47:20',3,'na','edX/E929/2014_T1'),(96119,'problem','i4x://edX/E929/problem/Sample_Algebraic_Problem',1091,'{\"correct_map\": {\"i4x-edX-E929-problem-Sample_Algebraic_Problem_2_1\": {\"hint\": \"\", \"hintmode\": null, \"correctness\": \"correct\", \"npoints\": null, \"msg\": \"\", \"queuestate\": null}}, \"input_state\": {\"i4x-edX-E929-problem-Sample_Algebraic_Problem_2_1\": {}}, \"attempts\": 1, \"seed\": 1, \"done\": true, \"student_answers\": {\"i4x-edX-E929-problem-Sample_Algebraic_Problem_2_1\": \"A*x^2 + sqrt(y)\", \"i4x-edX-E929-problem-Sample_Algebraic_Problem_2_1_dynamath\": \"<math xmlns=\\\"http://www.w3.org/1998/Math/MathML\\\">\\r\\n <mstyle displaystyle=\\\"true\\\">\\r\\n <mi>A</mi>\\r\\n <mo>&#x22C5;</mo>\\r\\n <msup>\\r\\n <mi>x</mi>\\r\\n <mn>2</mn>\\r\\n </msup>\\r\\n <mo>+</mo>\\r\\n <msqrt>\\r\\n <mrow>\\r\\n <mi>y</mi>\\r\\n </mrow>\\r\\n </msqrt>\\r\\n </mstyle>\\r\\n</math>\"}}',1,'2014-03-04 14:28:34','2014-04-11 18:47:11',1,'na','edX/E929/2014_T1'),(96120,'problem','i4x://edX/E929/problem/Sample_ChemFormula_Problem',1091,'{\"correct_map\": {\"i4x-edX-E929-problem-Sample_ChemFormula_Problem_2_1\": {\"hint\": \"\", \"hintmode\": null, \"correctness\": \"correct\", \"npoints\": 1, \"msg\": \"\", \"queuestate\": null}}, \"input_state\": {\"i4x-edX-E929-problem-Sample_ChemFormula_Problem_2_1\": {}}, \"attempts\": 1, \"seed\": 1, \"done\": true, \"student_answers\": {\"i4x-edX-E929-problem-Sample_ChemFormula_Problem_2_1\": \"H2SO4 -> H^+ + HSO4^-\"}}',1,'2014-03-04 14:28:34','2014-04-11 18:47:04',1,'na','edX/E929/2014_T1'),(96121,'problem','i4x://edX/E929/problem/75f9562c77bc4858b61f907bb810d974',1091,'{\"correct_map\": {\"i4x-edX-E929-problem-75f9562c77bc4858b61f907bb810d974_3_1\": {\"hint\": \"\", \"hintmode\": null, \"correctness\": \"incorrect\", \"npoints\": null, \"msg\": \"\", \"queuestate\": null}, \"i4x-edX-E929-problem-75f9562c77bc4858b61f907bb810d974_2_1\": {\"hint\": \"\", \"hintmode\": null, \"correctness\": \"correct\", \"npoints\": null, \"msg\": \"\", \"queuestate\": null}, \"i4x-edX-E929-problem-75f9562c77bc4858b61f907bb810d974_4_1\": {\"hint\": \"\", \"hintmode\": null, \"correctness\": \"correct\", \"npoints\": null, \"msg\": \"\", \"queuestate\": null}}, \"input_state\": {\"i4x-edX-E929-problem-75f9562c77bc4858b61f907bb810d974_3_1\": {}, \"i4x-edX-E929-problem-75f9562c77bc4858b61f907bb810d974_2_1\": {}, \"i4x-edX-E929-problem-75f9562c77bc4858b61f907bb810d974_4_1\": {}}, \"attempts\": 3, \"seed\": 1, \"done\": true, \"student_answers\": {\"i4x-edX-E929-problem-75f9562c77bc4858b61f907bb810d974_3_1\": \"546787\", \"i4x-edX-E929-problem-75f9562c77bc4858b61f907bb810d974_2_1\": \"3.14\", \"i4x-edX-E929-problem-75f9562c77bc4858b61f907bb810d974_4_1\": \"5\"}}',2,'2014-03-04 14:28:35','2014-04-11 18:46:46',3,'na','edX/E929/2014_T1'),(96122,'problem','i4x://edX/E929/problem/0d759dee4f9d459c8956136dbde55f02',1091,'{\"correct_map\": {\"i4x-edX-E929-problem-0d759dee4f9d459c8956136dbde55f02_2_1\": {\"hint\": \"\", \"hintmode\": null, \"correctness\": \"correct\", \"msg\": \"\", \"npoints\": null, \"queuestate\": null}}, \"input_state\": {\"i4x-edX-E929-problem-0d759dee4f9d459c8956136dbde55f02_2_1\": {}}, \"attempts\": 1, \"seed\": 1, \"done\": true, \"student_answers\": {\"i4x-edX-E929-problem-0d759dee4f9d459c8956136dbde55f02_2_1\": \"France\"}}',1,'2014-03-04 14:28:35','2014-04-11 18:46:20',1,'na','edX/E929/2014_T1'),(96123,'sequential','i4x://edX/E929/sequential/basic_questions',1091,'{\"position\": 1}',NULL,'2014-03-04 14:28:35','2014-04-11 18:47:37',NULL,'na','edX/E929/2014_T1'),(96124,'chapter','i4x://edX/E929/chapter/graded_interactions',1091,'{\"position\": 3}',NULL,'2014-03-04 14:28:48','2014-04-11 18:50:43',NULL,'na','edX/E929/2014_T1'),(96125,'problem','i4x://edX/E929/problem/700x_editmolB',1091,'{\"correct_map\": {\"i4x-edX-E929-problem-700x_editmolB_2_1\": {\"hint\": \"\", \"hintmode\": null, \"correctness\": \"incorrect\", \"msg\": \"\", \"npoints\": 0, \"queuestate\": null}}, \"input_state\": {\"i4x-edX-E929-problem-700x_editmolB_2_1\": {}}, \"attempts\": 3, \"seed\": 1, \"done\": true, \"student_answers\": {\"i4x-edX-E929-problem-700x_editmolB_2_1\": \"{\\\"mol\\\":\\\"NCCc1ccc(O)c(O)c1\\\\nJME 2013.01 Fri Apr 11 14:50:33 GMT-400 2014\\\\n \\\\n 11 11 0 0 0 0 0 0 0 0999 V2000\\\\n 7.2746 0.0000 0.0000 N 0 0 0 0 0 0 0 0 0 0 0 0\\\\n 0.0000 2.8000 0.0000 O 0 0 0 0 0 0 0 0 0 0 0 0\\\\n 0.0000 0.0000 0.0000 O 0 0 0 0 0 0 0 0 0 0 0 0\\\\n 2.4250 2.8000 0.0000 C 0 0 0 0 0 0 0 0 0 0 0 0\\\\n 3.6373 2.1000 0.0000 C 0 0 0 0 0 0 0 0 0 0 0 0\\\\n 2.4250 0.0000 0.0000 C 0 0 0 0 0 0 0 0 0 0 0 0\\\\n 6.0621 0.7000 0.0000 C 0 0 0 0 0 0 0 0 0 0 0 0\\\\n 4.8498 0.0000 0.0000 C 0 0 0 0 0 0 0 0 0 0 0 0\\\\n 1.2125 2.1000 0.0000 C 0 0 0 0 0 0 0 0 0 0 0 0\\\\n 1.2125 0.7000 0.0000 C 0 0 0 0 0 0 0 0 0 0 0 0\\\\n 3.6373 0.7000 0.0000 C 0 0 0 0 0 0 0 0 0 0 0 0\\\\n 1 7 1 0 0 0 0\\\\n 2 9 1 0 0 0 0\\\\n 3 10 1 0 0 0 0\\\\n 4 5 1 0 0 0 0\\\\n 4 9 2 0 0 0 0\\\\n 5 11 2 0 0 0 0\\\\n 6 10 2 0 0 0 0\\\\n 6 11 1 0 0 0 0\\\\n 7 8 1 0 0 0 0\\\\n 8 11 1 0 0 0 0\\\\n 9 10 1 0 0 0 0\\\\nM END\\\\n\\\",\\\"info\\\":[\\\"Hydrophobicity index = 0.490\\\",\\\"Can Make Strong Hydrogen Bonds\\\",\\\"Can not Make Ionic Bonds\\\"],\\\"error\\\":\\\"\\\"}\"}}',0,'2014-03-04 14:28:49','2014-04-11 18:50:34',1,'na','edX/E929/2014_T1'),(96126,'problem','i4x://edX/E929/problem/python_grader',1091,'{\"correct_map\": {\"i4x-edX-E929-problem-python_grader_2_1\": {\"hint\": \"\", \"hintmode\": null, \"correctness\": null, \"msg\": \"Unable to deliver your submission to grader (Reason: Queue \'edX-E929\' not found). Please try again later.\", \"npoints\": null, \"queuestate\": null}}, \"input_state\": {\"i4x-edX-E929-problem-python_grader_2_1\": {}}, \"attempts\": 1, \"seed\": 1, \"done\": true, \"student_answers\": {\"i4x-edX-E929-problem-python_grader_2_1\": \"def foo():\\r\\n print \'bar\'\"}}',0,'2014-03-04 14:28:49','2014-04-11 18:50:18',1,'na','edX/E929/2014_T1'),(96127,'problem','i4x://edX/E929/problem/free_form_simulation',1091,'{\"correct_map\": {\"i4x-edX-E929-problem-free_form_simulation_2_1\": {\"hint\": \"\", \"hintmode\": null, \"correctness\": \"correct\", \"npoints\": null, \"msg\": \"\", \"queuestate\": null}}, \"input_state\": {\"i4x-edX-E929-problem-free_form_simulation_2_1\": {}}, \"attempts\": 1, \"seed\": 1, \"done\": true, \"student_answers\": {\"i4x-edX-E929-problem-free_form_simulation_2_1\": \"[[\\\"r\\\",[168,128,0],{\\\"r\\\":\\\"1\\\",\\\"_json_\\\":0},[\\\"1\\\",\\\"2\\\"]],[\\\"r\\\",[168,80,0],{\\\"r\\\":\\\"1\\\",\\\"_json_\\\":1},[\\\"3\\\",\\\"1\\\"]],[\\\"v\\\",[88,80,0],{\\\"value\\\":\\\"dc(1)\\\",\\\"_json_\\\":2},[\\\"3\\\",\\\"2\\\"]],[\\\"w\\\",[88,80,168,80]],[\\\"w\\\",[88,128,168,176]],[\\\"s\\\",[168,128,0],{\\\"color\\\":\\\"cyan\\\",\\\"offset\\\":\\\"0\\\",\\\"_json_\\\":5},[\\\"1\\\"]],[\\\"view\\\",0,0,2,\\\"50\\\",\\\"10\\\",\\\"1G\\\",null,\\\"100\\\",\\\"1\\\",\\\"1000\\\"]]\"}}',1,'2014-03-04 14:28:49','2014-04-11 18:48:57',1,'na','edX/E929/2014_T1'),(96128,'problem','i4x://edX/E929/problem/logic_gate_problem',1091,'{\"correct_map\": {\"i4x-edX-E929-problem-logic_gate_problem_2_1\": {\"hint\": \"\", \"hintmode\": null, \"correctness\": \"incorrect\", \"npoints\": null, \"msg\": \"\", \"queuestate\": null}}, \"input_state\": {\"i4x-edX-E929-problem-logic_gate_problem_2_1\": {}}, \"attempts\": 1, \"seed\": 1, \"done\": true, \"student_answers\": {\"i4x-edX-E929-problem-logic_gate_problem_2_1\": \"[[\\\"w\\\",[128,192,112,192]],[\\\"w\\\",[104,192,112,192]],[\\\"s\\\",[112,192,0],{\\\"color\\\":\\\"blue\\\",\\\"offset\\\":\\\"5\\\",\\\"plot offset\\\":\\\"0\\\",\\\"_json_\\\":2},[\\\"C\\\"]],[\\\"w\\\",[128,144,112,144]],[\\\"w\\\",[104,144,112,144]],[\\\"s\\\",[112,144,0],{\\\"color\\\":\\\"green\\\",\\\"offset\\\":\\\"10\\\",\\\"plot offset\\\":\\\"0\\\",\\\"_json_\\\":5},[\\\"B\\\"]],[\\\"w\\\",[104,96,112,96]],[\\\"s\\\",[112,96,0],{\\\"color\\\":\\\"red\\\",\\\"offset\\\":\\\"15\\\",\\\"plot offset\\\":\\\"0\\\",\\\"_json_\\\":7},[\\\"A\\\"]],[\\\"w\\\",[192,96,192,112]],[\\\"w\\\",[96,192,104,192]],[\\\"L\\\",[96,192,2],{\\\"label\\\":\\\"C\\\",\\\"_json_\\\":10},[\\\"C\\\"]],[\\\"w\\\",[96,144,104,144]],[\\\"L\\\",[96,144,2],{\\\"label\\\":\\\"B\\\",\\\"_json_\\\":12},[\\\"B\\\"]],[\\\"w\\\",[96,96,104,96]],[\\\"L\\\",[96,96,2],{\\\"label\\\":\\\"A\\\",\\\"_json_\\\":14},[\\\"A\\\"]],[\\\"v\\\",[96,48,1],{\\\"name\\\":\\\"Vpwr\\\",\\\"value\\\":\\\"dc(3)\\\",\\\"_json_\\\":15},[\\\"1\\\",\\\"0\\\"]],[\\\"v\\\",[96,96,1],{\\\"name\\\":\\\"VA\\\",\\\"value\\\":\\\"square(3,0,1000K)\\\",\\\"_json_\\\":16},[\\\"A\\\",\\\"0\\\"]],[\\\"v\\\",[96,144,1],{\\\"name\\\":\\\"VB\\\",\\\"value\\\":\\\"square(3,0,500K)\\\",\\\"_json_\\\":17},[\\\"B\\\",\\\"0\\\"]],[\\\"v\\\",[96,192,1],{\\\"name\\\":\\\"VC\\\",\\\"value\\\":\\\"square(3,0,250K)\\\",\\\"_json_\\\":18},[\\\"C\\\",\\\"0\\\"]],[\\\"g\\\",[32,224,0],{\\\"_json_\\\":19},[\\\"0\\\"]],[\\\"w\\\",[32,48,48,48]],[\\\"w\\\",[48,96,32,96]],[\\\"w\\\",[32,48,32,96]],[\\\"w\\\",[48,144,32,144]],[\\\"w\\\",[32,96,32,144]],[\\\"w\\\",[48,192,32,192]],[\\\"w\\\",[32,224,32,192]],[\\\"w\\\",[32,144,32,192]],[\\\"r\\\",[192,48,0],{\\\"name\\\":\\\"Rpullup\\\",\\\"r\\\":\\\"10K\\\",\\\"_json_\\\":28},[\\\"1\\\",\\\"Z\\\"]],[\\\"L\\\",[256,96,3],{\\\"label\\\":\\\"Z\\\",\\\"_json_\\\":29},[\\\"Z\\\"]],[\\\"w\\\",[96,48,192,48]],[\\\"w\\\",[32,224,192,224]],[\\\"s\\\",[240,96,0],{\\\"color\\\":\\\"cyan\\\",\\\"offset\\\":\\\"\\\",\\\"plot offset\\\":\\\"0\\\",\\\"_json_\\\":32},[\\\"Z\\\"]],[\\\"w\\\",[192,96,240,96]],[\\\"w\\\",[256,96,240,96]],[\\\"w\\\",[112,96,128,96]],[\\\"view\\\",-7.099999999999994,6,1.953125,null,\\\"10\\\",\\\"10MEG\\\",null,\\\"100\\\",\\\"4us\\\",null]]\"}}',0,'2014-03-04 14:28:49','2014-04-11 18:49:34',1,'na','edX/E929/2014_T1'),(96129,'problem','i4x://edX/E929/problem/700x_proteinmake',1091,'{\"correct_map\": {\"i4x-edX-E929-problem-700x_proteinmake_2_1\": {\"hint\": \"\", \"hintmode\": null, \"correctness\": \"incorrect\", \"npoints\": 0, \"msg\": \"\", \"queuestate\": null}}, \"input_state\": {\"i4x-edX-E929-problem-700x_proteinmake_2_1\": {}}, \"attempts\": 1, \"seed\": 1, \"done\": true, \"student_answers\": {\"i4x-edX-E929-problem-700x_proteinmake_2_1\": \"{\\\"protex_answer\\\":\\\"INCORRECT\\\"}\"}}',0,'2014-03-04 14:28:49','2014-04-11 18:48:24',1,'na','edX/E929/2014_T1'),(96130,'sequential','i4x://edX/E929/sequential/graded_simulations',1091,'{\"position\": 1}',NULL,'2014-03-04 14:28:49','2014-04-11 18:50:41',NULL,'na','edX/E929/2014_T1'),(96131,'combinedopenended','i4x://edX/E929/combinedopenended/bb10fc2c57fc48b1a6c7228ca9be47ba',1091,'{\"ready_to_reset\": false, \"current_task_number\": 0, \"old_task_states\": [], \"task_states\": [\"{\\\"child_created\\\": false, \\\"child_attempts\\\": 0, \\\"stored_answer\\\": null, \\\"version\\\": 1, \\\"child_history\\\": [{\\\"answer\\\": \\\"foobar\\\"}], \\\"max_score\\\": 2, \\\"child_state\\\": \\\"assessing\\\"}\"], \"student_attempts\": 0, \"state\": \"assessing\"}',NULL,'2014-03-04 14:30:22','2014-04-11 18:50:44',NULL,'na','edX/E929/2014_T1'),(96132,'combinedopenended','i4x://edX/E929/combinedopenended/Humanities_SA_ML',1091,'{\"ready_to_reset\": false, \"current_task_number\": 0, \"old_task_states\": [], \"task_states\": [\"{\\\"child_created\\\": false, \\\"child_attempts\\\": 0, \\\"stored_answer\\\": null, \\\"version\\\": 1, \\\"child_history\\\": [], \\\"max_score\\\": 2, \\\"child_state\\\": \\\"initial\\\"}\"], \"student_attempts\": 0, \"state\": \"assessing\"}',NULL,'2014-03-04 14:30:22','2014-04-11 18:50:43',NULL,'na','edX/E929/2014_T1'),(96133,'combinedopenended','i4x://edX/E929/combinedopenended/90ffcb1647ab4957ab79bec6155bb046',1091,'{\"ready_to_reset\": false, \"current_task_number\": 0, \"old_task_states\": [], \"task_states\": [\"{\\\"child_created\\\": false, \\\"child_attempts\\\": 0, \\\"stored_answer\\\": null, \\\"version\\\": 1, \\\"child_history\\\": [], \\\"max_score\\\": 2, \\\"child_state\\\": \\\"initial\\\"}\"], \"student_attempts\": 0, \"state\": \"assessing\"}',NULL,'2014-03-04 14:30:23','2014-04-11 18:50:43',NULL,'na','edX/E929/2014_T1'),(96134,'combinedopenended','i4x://edX/E929/combinedopenended/1c055f72c03641149f2801ea1416ac50',1091,'{\"ready_to_reset\": false, \"current_task_number\": 0, \"old_task_states\": [], \"task_states\": [\"{\\\"child_created\\\": false, \\\"child_attempts\\\": 0, \\\"stored_answer\\\": null, \\\"version\\\": 1, \\\"child_history\\\": [], \\\"max_score\\\": 2, \\\"child_state\\\": \\\"initial\\\"}\"], \"student_attempts\": 0, \"state\": \"assessing\"}',NULL,'2014-03-04 14:30:23','2014-04-11 18:50:43',NULL,'na','edX/E929/2014_T1'),(96135,'sequential','i4x://edX/E929/sequential/machine_grading',1091,'{\"position\": 2}',NULL,'2014-03-04 14:30:23','2014-03-04 14:30:27',NULL,'na','edX/E929/2014_T1'),(96136,'chapter','i4x://edX/E929/chapter/1414ffd5143b4b508f739b563ab468b7',1091,'{\"position\": 1}',NULL,'2014-03-04 14:30:58','2014-03-04 14:30:58',NULL,'na','edX/E929/2014_T1'),(96137,'problem','i4x://edX/E929/problem/ex_practice_2',1091,'{\"correct_map\": {\"i4x-edX-E929-problem-ex_practice_2_2_1\": {\"hint\": \"\", \"hintmode\": null, \"correctness\": \"correct\", \"npoints\": null, \"msg\": \"\", \"queuestate\": null}}, \"input_state\": {\"i4x-edX-E929-problem-ex_practice_2_2_1\": {}}, \"attempts\": 1, \"seed\": 1, \"done\": true, \"student_answers\": {\"i4x-edX-E929-problem-ex_practice_2_2_1\": \"24\"}}',1,'2014-03-04 14:30:58','2014-03-04 14:31:08',1,'na','edX/E929/2014_T1'),(96138,'problem','i4x://edX/E929/problem/45d46192272c4f6db6b63586520bbdf4',1091,'{\"correct_map\": {\"i4x-edX-E929-problem-45d46192272c4f6db6b63586520bbdf4_2_1\": {\"hint\": \"\", \"hintmode\": null, \"correctness\": \"correct\", \"msg\": \"\", \"npoints\": null, \"queuestate\": null}}, \"input_state\": {\"i4x-edX-E929-problem-45d46192272c4f6db6b63586520bbdf4_2_1\": {}}, \"attempts\": 1, \"seed\": 1, \"done\": true, \"student_answers\": {\"i4x-edX-E929-problem-45d46192272c4f6db6b63586520bbdf4_2_1\": \"0\"}}',1,'2014-03-04 14:30:58','2014-03-04 14:31:20',1,'na','edX/E929/2014_T1'),(96139,'problem','i4x://edX/E929/problem/651e0945b77f42e0a4c89b8c3e6f5b3b',1091,'{\"correct_map\": {\"i4x-edX-E929-problem-651e0945b77f42e0a4c89b8c3e6f5b3b_2_1\": {\"hint\": \"\", \"hintmode\": null, \"correctness\": \"correct\", \"msg\": \"\", \"npoints\": null, \"queuestate\": null}}, \"input_state\": {\"i4x-edX-E929-problem-651e0945b77f42e0a4c89b8c3e6f5b3b_2_1\": {}}, \"attempts\": 2, \"seed\": 1, \"done\": true, \"student_answers\": {\"i4x-edX-E929-problem-651e0945b77f42e0a4c89b8c3e6f5b3b_2_1\": \"3.15\"}}',1,'2014-03-04 14:30:58','2014-03-04 14:31:47',1,'na','edX/E929/2014_T1'),(96140,'problem','i4x://edX/E929/problem/ex_practice_limited_checks',1091,'{\"seed\": 1, \"input_state\": {\"i4x-edX-E929-problem-ex_practice_limited_checks_2_1\": {}}}',NULL,'2014-03-04 14:30:58','2014-03-04 14:30:58',NULL,'na','edX/E929/2014_T1'),(96141,'problem','i4x://edX/E929/problem/d1b84dcd39b0423d9e288f27f0f7f242',1091,'{\"correct_map\": {\"i4x-edX-E929-problem-d1b84dcd39b0423d9e288f27f0f7f242_2_1\": {\"hint\": \"\", \"hintmode\": null, \"correctness\": \"correct\", \"msg\": \"\", \"npoints\": null, \"queuestate\": null}}, \"input_state\": {\"i4x-edX-E929-problem-d1b84dcd39b0423d9e288f27f0f7f242_2_1\": {}}, \"attempts\": 3, \"seed\": 1, \"done\": true, \"student_answers\": {\"i4x-edX-E929-problem-d1b84dcd39b0423d9e288f27f0f7f242_2_1\": \"choice_0\"}}',1,'2014-03-04 14:30:58','2014-03-04 14:32:12',1,'na','edX/E929/2014_T1'),(96142,'problem','i4x://edX/E929/problem/ex_practice_3',1091,'{\"correct_map\": {\"i4x-edX-E929-problem-ex_practice_3_2_1\": {\"hint\": \"\", \"hintmode\": null, \"correctness\": \"correct\", \"msg\": \"\", \"npoints\": null, \"queuestate\": null}}, \"input_state\": {\"i4x-edX-E929-problem-ex_practice_3_2_1\": {}}, \"attempts\": 3, \"seed\": 596, \"done\": true, \"student_answers\": {\"i4x-edX-E929-problem-ex_practice_3_2_1\": \"133\"}}',1,'2014-03-04 14:30:59','2014-04-11 18:51:14',1,'na','edX/E929/2014_T1'),(96143,'sequential','i4x://edX/E929/sequential/workflow',1091,'{\"position\": 6}',NULL,'2014-03-04 14:30:59','2014-04-11 18:50:58',NULL,'na','edX/E929/2014_T1'),(97241,'course','i4x://edX/E929/course/2014_T1',570,'{\"position\": 3}',NULL,'2014-04-08 13:46:27','2014-04-08 13:46:31',NULL,'na','edX/E929/2014_T1'),(97242,'chapter','i4x://edX/E929/chapter/d8a6192ade314473a78242dfeedfbf5b',570,'{\"position\": 1}',NULL,'2014-04-08 13:46:27','2014-04-08 13:46:27',NULL,'na','edX/E929/2014_T1'),(97243,'sequential','i4x://edX/E929/sequential/edx_introduction',570,'{\"position\": 1}',NULL,'2014-04-08 13:46:27','2014-04-08 13:46:27',NULL,'na','edX/E929/2014_T1'),(97244,'chapter','i4x://edX/E929/chapter/graded_interactions',570,'{\"position\": 3}',NULL,'2014-04-08 13:46:31','2014-04-08 13:46:31',NULL,'na','edX/E929/2014_T1'),(97245,'combinedopenended','i4x://edX/E929/combinedopenended/bb10fc2c57fc48b1a6c7228ca9be47ba',570,'{\"ready_to_reset\": false, \"current_task_number\": 0, \"old_task_states\": [], \"task_states\": [\"{\\\"child_created\\\": false, \\\"child_attempts\\\": 0, \\\"stored_answer\\\": null, \\\"version\\\": 1, \\\"child_history\\\": [], \\\"max_score\\\": 2, \\\"child_state\\\": \\\"initial\\\"}\"], \"student_attempts\": 0, \"state\": \"assessing\"}',NULL,'2014-04-08 13:46:32','2014-04-08 14:32:02',NULL,'na','edX/E929/2014_T1'),(97246,'combinedopenended','i4x://edX/E929/combinedopenended/Humanities_SA_ML',570,'{\"ready_to_reset\": false, \"current_task_number\": 0, \"old_task_states\": [], \"task_states\": [\"{\\\"child_created\\\": false, \\\"child_attempts\\\": 0, \\\"stored_answer\\\": null, \\\"version\\\": 1, \\\"child_history\\\": [], \\\"max_score\\\": 2, \\\"child_state\\\": \\\"initial\\\"}\"], \"student_attempts\": 0, \"state\": \"assessing\"}',NULL,'2014-04-08 13:46:32','2014-04-08 14:32:02',NULL,'na','edX/E929/2014_T1'),(97247,'combinedopenended','i4x://edX/E929/combinedopenended/90ffcb1647ab4957ab79bec6155bb046',570,'{\"ready_to_reset\": false, \"current_task_number\": 0, \"old_task_states\": [], \"task_states\": [\"{\\\"child_created\\\": false, \\\"child_attempts\\\": 0, \\\"stored_answer\\\": null, \\\"version\\\": 1, \\\"child_history\\\": [], \\\"max_score\\\": 2, \\\"child_state\\\": \\\"initial\\\"}\"], \"student_attempts\": 0, \"state\": \"assessing\"}',NULL,'2014-04-08 13:46:32','2014-04-08 14:32:04',NULL,'na','edX/E929/2014_T1'),(97248,'combinedopenended','i4x://edX/E929/combinedopenended/1c055f72c03641149f2801ea1416ac50',570,'{\"ready_to_reset\": false, \"current_task_number\": 0, \"old_task_states\": [], \"task_states\": [\"{\\\"child_created\\\": false, \\\"child_attempts\\\": 0, \\\"stored_answer\\\": null, \\\"version\\\": 1, \\\"child_history\\\": [], \\\"max_score\\\": 2, \\\"child_state\\\": \\\"initial\\\"}\"], \"student_attempts\": 0, \"state\": \"assessing\"}',NULL,'2014-04-08 13:46:32','2014-04-08 14:32:02',NULL,'na','edX/E929/2014_T1'),(97249,'sequential','i4x://edX/E929/sequential/machine_grading',570,'{\"position\": 4}',NULL,'2014-04-08 13:46:33','2014-04-08 13:46:39',NULL,'na','edX/E929/2014_T1'),(97279,'chapter','i4x://edX/E929/chapter/social_integration',1091,'{\"position\": 2}',NULL,'2014-04-11 18:50:48','2014-04-11 18:50:48',NULL,'na','edX/E929/2014_T1'),(97280,'sequential','i4x://edX/E929/sequential/dbe8fc027bcb4fe9afb744d2e8415855',1091,'{\"position\": 1}',NULL,'2014-04-11 18:50:48','2014-04-11 18:50:48',NULL,'na','edX/E929/2014_T1');
-- Dump completed on 2014-04-11 18:52:44
96112 course i4x://edX/E929/course/2014_T1 1091 {"position": 5} NULL 2014-03-04 14:28:27 2014-04-11 18:50:52 NULL na edX/E929/2014_T1
96113 chapter i4x://edX/E929/chapter/d8a6192ade314473a78242dfeedfbf5b 1091 {"position": 1} NULL 2014-03-04 14:28:27 2014-03-04 14:28:27 NULL na edX/E929/2014_T1
96114 sequential i4x://edX/E929/sequential/edx_introduction 1091 {"position": 1} NULL 2014-03-04 14:28:28 2014-03-04 14:28:28 NULL na edX/E929/2014_T1
96115 chapter i4x://edX/E929/chapter/interactive_demonstrations 1091 {"position": 2} NULL 2014-03-04 14:28:34 2014-03-04 14:28:34 NULL na edX/E929/2014_T1
96116 problem i4x://edX/E929/problem/c554538a57664fac80783b99d9d6da7c 1091 {"correct_map": {"i4x-edX-E929-problem-c554538a57664fac80783b99d9d6da7c_2_1": {"hint": "", "hintmode": null, "correctness": "correct", "msg": "", "npoints": null, "queuestate": null}}, "input_state": {"i4x-edX-E929-problem-c554538a57664fac80783b99d9d6da7c_2_1": {}}, "attempts": 1, "seed": 1, "done": true, "student_answers": {"i4x-edX-E929-problem-c554538a57664fac80783b99d9d6da7c_2_1": "[482,173]"}} 1 2014-03-04 14:28:34 2014-04-11 18:47:43 1 na edX/E929/2014_T1
96117 problem i4x://edX/E929/problem/d2e35c1d294b4ba0b3b1048615605d2a 1091 {"correct_map": {"i4x-edX-E929-problem-d2e35c1d294b4ba0b3b1048615605d2a_2_1": {"hint": "", "hintmode": null, "correctness": "incorrect", "npoints": 0, "msg": "", "queuestate": null}}, "input_state": {"i4x-edX-E929-problem-d2e35c1d294b4ba0b3b1048615605d2a_2_1": {}}, "attempts": 1, "seed": 1, "done": true, "student_answers": {"i4x-edX-E929-problem-d2e35c1d294b4ba0b3b1048615605d2a_2_1": "[{\\"1\\":[155.5,147]},{\\"2\\":[244.5,146]},{\\"3\\":[66.5,169]},{\\"4\\":[281.5,146]},{\\"5\\":[78.5,191]},{\\"6\\":[306.5,171]},{\\"7\\":[536.5,150]},{\\"8\\":[420.5,170]},{\\"9\\":[201.5,181]},{\\"10\\":[408.5,164]}]"}} 0 2014-03-04 14:28:34 2014-04-11 18:47:35 1 na edX/E929/2014_T1
96118 problem i4x://edX/E929/problem/a0effb954cca4759994f1ac9e9434bf4 1091 {"correct_map": {"i4x-edX-E929-problem-a0effb954cca4759994f1ac9e9434bf4_4_1": {"hint": "", "hintmode": null, "correctness": "incorrect", "npoints": null, "msg": "", "queuestate": null}, "i4x-edX-E929-problem-a0effb954cca4759994f1ac9e9434bf4_3_1": {"hint": "", "hintmode": null, "correctness": "incorrect", "npoints": null, "msg": "", "queuestate": null}, "i4x-edX-E929-problem-a0effb954cca4759994f1ac9e9434bf4_2_1": {"hint": "", "hintmode": null, "correctness": "correct", "npoints": null, "msg": "", "queuestate": null}}, "input_state": {"i4x-edX-E929-problem-a0effb954cca4759994f1ac9e9434bf4_4_1": {}, "i4x-edX-E929-problem-a0effb954cca4759994f1ac9e9434bf4_3_1": {}, "i4x-edX-E929-problem-a0effb954cca4759994f1ac9e9434bf4_2_1": {}}, "attempts": 1, "seed": 1, "done": true, "student_answers": {"i4x-edX-E929-problem-a0effb954cca4759994f1ac9e9434bf4_4_1": ["choice_1", "choice_2", "choice_3"], "i4x-edX-E929-problem-a0effb954cca4759994f1ac9e9434bf4_3_1": "choice_0", "i4x-edX-E929-problem-a0effb954cca4759994f1ac9e9434bf4_2_1": "blue"}} 1 2014-03-04 14:28:34 2014-04-11 18:47:20 3 na edX/E929/2014_T1
96119 problem i4x://edX/E929/problem/Sample_Algebraic_Problem 1091 {"correct_map": {"i4x-edX-E929-problem-Sample_Algebraic_Problem_2_1": {"hint": "", "hintmode": null, "correctness": "correct", "npoints": null, "msg": "", "queuestate": null}}, "input_state": {"i4x-edX-E929-problem-Sample_Algebraic_Problem_2_1": {}}, "attempts": 1, "seed": 1, "done": true, "student_answers": {"i4x-edX-E929-problem-Sample_Algebraic_Problem_2_1": "A*x^2 + sqrt(y)", "i4x-edX-E929-problem-Sample_Algebraic_Problem_2_1_dynamath": "<math xmlns=\\"http://www.w3.org/1998/Math/MathML\\">\\r\\n <mstyle displaystyle=\\"true\\">\\r\\n <mi>A</mi>\\r\\n <mo>&#x22C5;</mo>\\r\\n <msup>\\r\\n <mi>x</mi>\\r\\n <mn>2</mn>\\r\\n </msup>\\r\\n <mo>+</mo>\\r\\n <msqrt>\\r\\n <mrow>\\r\\n <mi>y</mi>\\r\\n </mrow>\\r\\n </msqrt>\\r\\n </mstyle>\\r\\n</math>"}} 1 2014-03-04 14:28:34 2014-04-11 18:47:11 1 na edX/E929/2014_T1
96120 problem i4x://edX/E929/problem/Sample_ChemFormula_Problem 1091 {"correct_map": {"i4x-edX-E929-problem-Sample_ChemFormula_Problem_2_1": {"hint": "", "hintmode": null, "correctness": "correct", "npoints": 1, "msg": "", "queuestate": null}}, "input_state": {"i4x-edX-E929-problem-Sample_ChemFormula_Problem_2_1": {}}, "attempts": 1, "seed": 1, "done": true, "student_answers": {"i4x-edX-E929-problem-Sample_ChemFormula_Problem_2_1": "H2SO4 -> H^+ + HSO4^-"}} 1 2014-03-04 14:28:34 2014-04-11 18:47:04 1 na edX/E929/2014_T1
96121 problem i4x://edX/E929/problem/75f9562c77bc4858b61f907bb810d974 1091 {"correct_map": {"i4x-edX-E929-problem-75f9562c77bc4858b61f907bb810d974_3_1": {"hint": "", "hintmode": null, "correctness": "incorrect", "npoints": null, "msg": "", "queuestate": null}, "i4x-edX-E929-problem-75f9562c77bc4858b61f907bb810d974_2_1": {"hint": "", "hintmode": null, "correctness": "correct", "npoints": null, "msg": "", "queuestate": null}, "i4x-edX-E929-problem-75f9562c77bc4858b61f907bb810d974_4_1": {"hint": "", "hintmode": null, "correctness": "correct", "npoints": null, "msg": "", "queuestate": null}}, "input_state": {"i4x-edX-E929-problem-75f9562c77bc4858b61f907bb810d974_3_1": {}, "i4x-edX-E929-problem-75f9562c77bc4858b61f907bb810d974_2_1": {}, "i4x-edX-E929-problem-75f9562c77bc4858b61f907bb810d974_4_1": {}}, "attempts": 3, "seed": 1, "done": true, "student_answers": {"i4x-edX-E929-problem-75f9562c77bc4858b61f907bb810d974_3_1": "546787", "i4x-edX-E929-problem-75f9562c77bc4858b61f907bb810d974_2_1": "3.14", "i4x-edX-E929-problem-75f9562c77bc4858b61f907bb810d974_4_1": "5"}} 2 2014-03-04 14:28:35 2014-04-11 18:46:46 3 na edX/E929/2014_T1
96122 problem i4x://edX/E929/problem/0d759dee4f9d459c8956136dbde55f02 1091 {"correct_map": {"i4x-edX-E929-problem-0d759dee4f9d459c8956136dbde55f02_2_1": {"hint": "", "hintmode": null, "correctness": "correct", "msg": "", "npoints": null, "queuestate": null}}, "input_state": {"i4x-edX-E929-problem-0d759dee4f9d459c8956136dbde55f02_2_1": {}}, "attempts": 1, "seed": 1, "done": true, "student_answers": {"i4x-edX-E929-problem-0d759dee4f9d459c8956136dbde55f02_2_1": "France"}} 1 2014-03-04 14:28:35 2014-04-11 18:46:20 1 na edX/E929/2014_T1
96123 sequential i4x://edX/E929/sequential/basic_questions 1091 {"position": 1} NULL 2014-03-04 14:28:35 2014-04-11 18:47:37 NULL na edX/E929/2014_T1
96124 chapter i4x://edX/E929/chapter/graded_interactions 1091 {"position": 3} NULL 2014-03-04 14:28:48 2014-04-11 18:50:43 NULL na edX/E929/2014_T1
96125 problem i4x://edX/E929/problem/700x_editmolB 1091 {"correct_map": {"i4x-edX-E929-problem-700x_editmolB_2_1": {"hint": "", "hintmode": null, "correctness": "incorrect", "msg": "", "npoints": 0, "queuestate": null}}, "input_state": {"i4x-edX-E929-problem-700x_editmolB_2_1": {}}, "attempts": 3, "seed": 1, "done": true, "student_answers": {"i4x-edX-E929-problem-700x_editmolB_2_1": "{\\"mol\\":\\"NCCc1ccc(O)c(O)c1\\\\nJME 2013.01 Fri Apr 11 14:50:33 GMT-400 2014\\\\n \\\\n 11 11 0 0 0 0 0 0 0 0999 V2000\\\\n 7.2746 0.0000 0.0000 N 0 0 0 0 0 0 0 0 0 0 0 0\\\\n 0.0000 2.8000 0.0000 O 0 0 0 0 0 0 0 0 0 0 0 0\\\\n 0.0000 0.0000 0.0000 O 0 0 0 0 0 0 0 0 0 0 0 0\\\\n 2.4250 2.8000 0.0000 C 0 0 0 0 0 0 0 0 0 0 0 0\\\\n 3.6373 2.1000 0.0000 C 0 0 0 0 0 0 0 0 0 0 0 0\\\\n 2.4250 0.0000 0.0000 C 0 0 0 0 0 0 0 0 0 0 0 0\\\\n 6.0621 0.7000 0.0000 C 0 0 0 0 0 0 0 0 0 0 0 0\\\\n 4.8498 0.0000 0.0000 C 0 0 0 0 0 0 0 0 0 0 0 0\\\\n 1.2125 2.1000 0.0000 C 0 0 0 0 0 0 0 0 0 0 0 0\\\\n 1.2125 0.7000 0.0000 C 0 0 0 0 0 0 0 0 0 0 0 0\\\\n 3.6373 0.7000 0.0000 C 0 0 0 0 0 0 0 0 0 0 0 0\\\\n 1 7 1 0 0 0 0\\\\n 2 9 1 0 0 0 0\\\\n 3 10 1 0 0 0 0\\\\n 4 5 1 0 0 0 0\\\\n 4 9 2 0 0 0 0\\\\n 5 11 2 0 0 0 0\\\\n 6 10 2 0 0 0 0\\\\n 6 11 1 0 0 0 0\\\\n 7 8 1 0 0 0 0\\\\n 8 11 1 0 0 0 0\\\\n 9 10 1 0 0 0 0\\\\nM END\\\\n\\",\\"info\\":[\\"Hydrophobicity index = 0.490\\",\\"Can Make Strong Hydrogen Bonds\\",\\"Can not Make Ionic Bonds\\"],\\"error\\":\\"\\"}"}} 0 2014-03-04 14:28:49 2014-04-11 18:50:34 1 na edX/E929/2014_T1
96126 problem i4x://edX/E929/problem/python_grader 1091 {"correct_map": {"i4x-edX-E929-problem-python_grader_2_1": {"hint": "", "hintmode": null, "correctness": null, "msg": "Unable to deliver your submission to grader (Reason: Queue 'edX-E929' not found). Please try again later.", "npoints": null, "queuestate": null}}, "input_state": {"i4x-edX-E929-problem-python_grader_2_1": {}}, "attempts": 1, "seed": 1, "done": true, "student_answers": {"i4x-edX-E929-problem-python_grader_2_1": "def foo():\\r\\n print 'bar'"}} 0 2014-03-04 14:28:49 2014-04-11 18:50:18 1 na edX/E929/2014_T1
96127 problem i4x://edX/E929/problem/free_form_simulation 1091 {"correct_map": {"i4x-edX-E929-problem-free_form_simulation_2_1": {"hint": "", "hintmode": null, "correctness": "correct", "npoints": null, "msg": "", "queuestate": null}}, "input_state": {"i4x-edX-E929-problem-free_form_simulation_2_1": {}}, "attempts": 1, "seed": 1, "done": true, "student_answers": {"i4x-edX-E929-problem-free_form_simulation_2_1": "[[\\"r\\",[168,128,0],{\\"r\\":\\"1\\",\\"_json_\\":0},[\\"1\\",\\"2\\"]],[\\"r\\",[168,80,0],{\\"r\\":\\"1\\",\\"_json_\\":1},[\\"3\\",\\"1\\"]],[\\"v\\",[88,80,0],{\\"value\\":\\"dc(1)\\",\\"_json_\\":2},[\\"3\\",\\"2\\"]],[\\"w\\",[88,80,168,80]],[\\"w\\",[88,128,168,176]],[\\"s\\",[168,128,0],{\\"color\\":\\"cyan\\",\\"offset\\":\\"0\\",\\"_json_\\":5},[\\"1\\"]],[\\"view\\",0,0,2,\\"50\\",\\"10\\",\\"1G\\",null,\\"100\\",\\"1\\",\\"1000\\"]]"}} 1 2014-03-04 14:28:49 2014-04-11 18:48:57 1 na edX/E929/2014_T1
96128 problem i4x://edX/E929/problem/logic_gate_problem 1091 {"correct_map": {"i4x-edX-E929-problem-logic_gate_problem_2_1": {"hint": "", "hintmode": null, "correctness": "incorrect", "npoints": null, "msg": "", "queuestate": null}}, "input_state": {"i4x-edX-E929-problem-logic_gate_problem_2_1": {}}, "attempts": 1, "seed": 1, "done": true, "student_answers": {"i4x-edX-E929-problem-logic_gate_problem_2_1": "[[\\"w\\",[128,192,112,192]],[\\"w\\",[104,192,112,192]],[\\"s\\",[112,192,0],{\\"color\\":\\"blue\\",\\"offset\\":\\"5\\",\\"plot offset\\":\\"0\\",\\"_json_\\":2},[\\"C\\"]],[\\"w\\",[128,144,112,144]],[\\"w\\",[104,144,112,144]],[\\"s\\",[112,144,0],{\\"color\\":\\"green\\",\\"offset\\":\\"10\\",\\"plot offset\\":\\"0\\",\\"_json_\\":5},[\\"B\\"]],[\\"w\\",[104,96,112,96]],[\\"s\\",[112,96,0],{\\"color\\":\\"red\\",\\"offset\\":\\"15\\",\\"plot offset\\":\\"0\\",\\"_json_\\":7},[\\"A\\"]],[\\"w\\",[192,96,192,112]],[\\"w\\",[96,192,104,192]],[\\"L\\",[96,192,2],{\\"label\\":\\"C\\",\\"_json_\\":10},[\\"C\\"]],[\\"w\\",[96,144,104,144]],[\\"L\\",[96,144,2],{\\"label\\":\\"B\\",\\"_json_\\":12},[\\"B\\"]],[\\"w\\",[96,96,104,96]],[\\"L\\",[96,96,2],{\\"label\\":\\"A\\",\\"_json_\\":14},[\\"A\\"]],[\\"v\\",[96,48,1],{\\"name\\":\\"Vpwr\\",\\"value\\":\\"dc(3)\\",\\"_json_\\":15},[\\"1\\",\\"0\\"]],[\\"v\\",[96,96,1],{\\"name\\":\\"VA\\",\\"value\\":\\"square(3,0,1000K)\\",\\"_json_\\":16},[\\"A\\",\\"0\\"]],[\\"v\\",[96,144,1],{\\"name\\":\\"VB\\",\\"value\\":\\"square(3,0,500K)\\",\\"_json_\\":17},[\\"B\\",\\"0\\"]],[\\"v\\",[96,192,1],{\\"name\\":\\"VC\\",\\"value\\":\\"square(3,0,250K)\\",\\"_json_\\":18},[\\"C\\",\\"0\\"]],[\\"g\\",[32,224,0],{\\"_json_\\":19},[\\"0\\"]],[\\"w\\",[32,48,48,48]],[\\"w\\",[48,96,32,96]],[\\"w\\",[32,48,32,96]],[\\"w\\",[48,144,32,144]],[\\"w\\",[32,96,32,144]],[\\"w\\",[48,192,32,192]],[\\"w\\",[32,224,32,192]],[\\"w\\",[32,144,32,192]],[\\"r\\",[192,48,0],{\\"name\\":\\"Rpullup\\",\\"r\\":\\"10K\\",\\"_json_\\":28},[\\"1\\",\\"Z\\"]],[\\"L\\",[256,96,3],{\\"label\\":\\"Z\\",\\"_json_\\":29},[\\"Z\\"]],[\\"w\\",[96,48,192,48]],[\\"w\\",[32,224,192,224]],[\\"s\\",[240,96,0],{\\"color\\":\\"cyan\\",\\"offset\\":\\"\\",\\"plot offset\\":\\"0\\",\\"_json_\\":32},[\\"Z\\"]],[\\"w\\",[192,96,240,96]],[\\"w\\",[256,96,240,96]],[\\"w\\",[112,96,128,96]],[\\"view\\",-7.099999999999994,6,1.953125,null,\\"10\\",\\"10MEG\\",null,\\"100\\",\\"4us\\",null]]"}} 0 2014-03-04 14:28:49 2014-04-11 18:49:34 1 na edX/E929/2014_T1
96129 problem i4x://edX/E929/problem/700x_proteinmake 1091 {"correct_map": {"i4x-edX-E929-problem-700x_proteinmake_2_1": {"hint": "", "hintmode": null, "correctness": "incorrect", "npoints": 0, "msg": "", "queuestate": null}}, "input_state": {"i4x-edX-E929-problem-700x_proteinmake_2_1": {}}, "attempts": 1, "seed": 1, "done": true, "student_answers": {"i4x-edX-E929-problem-700x_proteinmake_2_1": "{\\"protex_answer\\":\\"INCORRECT\\"}"}} 0 2014-03-04 14:28:49 2014-04-11 18:48:24 1 na edX/E929/2014_T1
96130 sequential i4x://edX/E929/sequential/graded_simulations 1091 {"position": 1} NULL 2014-03-04 14:28:49 2014-04-11 18:50:41 NULL na edX/E929/2014_T1
96131 combinedopenended i4x://edX/E929/combinedopenended/bb10fc2c57fc48b1a6c7228ca9be47ba 1091 {"ready_to_reset": false, "current_task_number": 0, "old_task_states": [], "task_states": ["{\\"child_created\\": false, \\"child_attempts\\": 0, \\"stored_answer\\": null, \\"version\\": 1, \\"child_history\\": [{\\"answer\\": \\"foobar\\"}], \\"max_score\\": 2, \\"child_state\\": \\"assessing\\"}"], "student_attempts": 0, "state": "assessing"} NULL 2014-03-04 14:30:22 2014-04-11 18:50:44 NULL na edX/E929/2014_T1
96132 combinedopenended i4x://edX/E929/combinedopenended/Humanities_SA_ML 1091 {"ready_to_reset": false, "current_task_number": 0, "old_task_states": [], "task_states": ["{\\"child_created\\": false, \\"child_attempts\\": 0, \\"stored_answer\\": null, \\"version\\": 1, \\"child_history\\": [], \\"max_score\\": 2, \\"child_state\\": \\"initial\\"}"], "student_attempts": 0, "state": "assessing"} NULL 2014-03-04 14:30:22 2014-04-11 18:50:43 NULL na edX/E929/2014_T1
96133 combinedopenended i4x://edX/E929/combinedopenended/90ffcb1647ab4957ab79bec6155bb046 1091 {"ready_to_reset": false, "current_task_number": 0, "old_task_states": [], "task_states": ["{\\"child_created\\": false, \\"child_attempts\\": 0, \\"stored_answer\\": null, \\"version\\": 1, \\"child_history\\": [], \\"max_score\\": 2, \\"child_state\\": \\"initial\\"}"], "student_attempts": 0, "state": "assessing"} NULL 2014-03-04 14:30:23 2014-04-11 18:50:43 NULL na edX/E929/2014_T1
96134 combinedopenended i4x://edX/E929/combinedopenended/1c055f72c03641149f2801ea1416ac50 1091 {"ready_to_reset": false, "current_task_number": 0, "old_task_states": [], "task_states": ["{\\"child_created\\": false, \\"child_attempts\\": 0, \\"stored_answer\\": null, \\"version\\": 1, \\"child_history\\": [], \\"max_score\\": 2, \\"child_state\\": \\"initial\\"}"], "student_attempts": 0, "state": "assessing"} NULL 2014-03-04 14:30:23 2014-04-11 18:50:43 NULL na edX/E929/2014_T1
96135 sequential i4x://edX/E929/sequential/machine_grading 1091 {"position": 2} NULL 2014-03-04 14:30:23 2014-03-04 14:30:27 NULL na edX/E929/2014_T1
96136 chapter i4x://edX/E929/chapter/1414ffd5143b4b508f739b563ab468b7 1091 {"position": 1} NULL 2014-03-04 14:30:58 2014-03-04 14:30:58 NULL na edX/E929/2014_T1
96137 problem i4x://edX/E929/problem/ex_practice_2 1091 {"correct_map": {"i4x-edX-E929-problem-ex_practice_2_2_1": {"hint": "", "hintmode": null, "correctness": "correct", "npoints": null, "msg": "", "queuestate": null}}, "input_state": {"i4x-edX-E929-problem-ex_practice_2_2_1": {}}, "attempts": 1, "seed": 1, "done": true, "student_answers": {"i4x-edX-E929-problem-ex_practice_2_2_1": "24"}} 1 2014-03-04 14:30:58 2014-03-04 14:31:08 1 na edX/E929/2014_T1
96138 problem i4x://edX/E929/problem/45d46192272c4f6db6b63586520bbdf4 1091 {"correct_map": {"i4x-edX-E929-problem-45d46192272c4f6db6b63586520bbdf4_2_1": {"hint": "", "hintmode": null, "correctness": "correct", "msg": "", "npoints": null, "queuestate": null}}, "input_state": {"i4x-edX-E929-problem-45d46192272c4f6db6b63586520bbdf4_2_1": {}}, "attempts": 1, "seed": 1, "done": true, "student_answers": {"i4x-edX-E929-problem-45d46192272c4f6db6b63586520bbdf4_2_1": "0"}} 1 2014-03-04 14:30:58 2014-03-04 14:31:20 1 na edX/E929/2014_T1
96139 problem i4x://edX/E929/problem/651e0945b77f42e0a4c89b8c3e6f5b3b 1091 {"correct_map": {"i4x-edX-E929-problem-651e0945b77f42e0a4c89b8c3e6f5b3b_2_1": {"hint": "", "hintmode": null, "correctness": "correct", "msg": "", "npoints": null, "queuestate": null}}, "input_state": {"i4x-edX-E929-problem-651e0945b77f42e0a4c89b8c3e6f5b3b_2_1": {}}, "attempts": 2, "seed": 1, "done": true, "student_answers": {"i4x-edX-E929-problem-651e0945b77f42e0a4c89b8c3e6f5b3b_2_1": "3.15"}} 1 2014-03-04 14:30:58 2014-03-04 14:31:47 1 na edX/E929/2014_T1
96140 problem i4x://edX/E929/problem/ex_practice_limited_checks 1091 {"seed": 1, "input_state": {"i4x-edX-E929-problem-ex_practice_limited_checks_2_1": {}}} NULL 2014-03-04 14:30:58 2014-03-04 14:30:58 NULL na edX/E929/2014_T1
96141 problem i4x://edX/E929/problem/d1b84dcd39b0423d9e288f27f0f7f242 1091 {"correct_map": {"i4x-edX-E929-problem-d1b84dcd39b0423d9e288f27f0f7f242_2_1": {"hint": "", "hintmode": null, "correctness": "correct", "msg": "", "npoints": null, "queuestate": null}}, "input_state": {"i4x-edX-E929-problem-d1b84dcd39b0423d9e288f27f0f7f242_2_1": {}}, "attempts": 3, "seed": 1, "done": true, "student_answers": {"i4x-edX-E929-problem-d1b84dcd39b0423d9e288f27f0f7f242_2_1": "choice_0"}} 1 2014-03-04 14:30:58 2014-03-04 14:32:12 1 na edX/E929/2014_T1
96142 problem i4x://edX/E929/problem/ex_practice_3 1091 {"correct_map": {"i4x-edX-E929-problem-ex_practice_3_2_1": {"hint": "", "hintmode": null, "correctness": "correct", "msg": "", "npoints": null, "queuestate": null}}, "input_state": {"i4x-edX-E929-problem-ex_practice_3_2_1": {}}, "attempts": 3, "seed": 596, "done": true, "student_answers": {"i4x-edX-E929-problem-ex_practice_3_2_1": "133"}} 1 2014-03-04 14:30:59 2014-04-11 18:51:14 1 na edX/E929/2014_T1
96143 sequential i4x://edX/E929/sequential/workflow 1091 {"position": 6} NULL 2014-03-04 14:30:59 2014-04-11 18:50:58 NULL na edX/E929/2014_T1
97241 course i4x://edX/E929/course/2014_T1 570 {"position": 3} NULL 2014-04-08 13:46:27 2014-04-08 13:46:31 NULL na edX/E929/2014_T1
97242 chapter i4x://edX/E929/chapter/d8a6192ade314473a78242dfeedfbf5b 570 {"position": 1} NULL 2014-04-08 13:46:27 2014-04-08 13:46:27 NULL na edX/E929/2014_T1
97243 sequential i4x://edX/E929/sequential/edx_introduction 570 {"position": 1} NULL 2014-04-08 13:46:27 2014-04-08 13:46:27 NULL na edX/E929/2014_T1
97244 chapter i4x://edX/E929/chapter/graded_interactions 570 {"position": 3} NULL 2014-04-08 13:46:31 2014-04-08 13:46:31 NULL na edX/E929/2014_T1
97245 combinedopenended i4x://edX/E929/combinedopenended/bb10fc2c57fc48b1a6c7228ca9be47ba 570 {"ready_to_reset": false, "current_task_number": 0, "old_task_states": [], "task_states": ["{\\"child_created\\": false, \\"child_attempts\\": 0, \\"stored_answer\\": null, \\"version\\": 1, \\"child_history\\": [], \\"max_score\\": 2, \\"child_state\\": \\"initial\\"}"], "student_attempts": 0, "state": "assessing"} NULL 2014-04-08 13:46:32 2014-04-08 14:32:02 NULL na edX/E929/2014_T1
97246 combinedopenended i4x://edX/E929/combinedopenended/Humanities_SA_ML 570 {"ready_to_reset": false, "current_task_number": 0, "old_task_states": [], "task_states": ["{\\"child_created\\": false, \\"child_attempts\\": 0, \\"stored_answer\\": null, \\"version\\": 1, \\"child_history\\": [], \\"max_score\\": 2, \\"child_state\\": \\"initial\\"}"], "student_attempts": 0, "state": "assessing"} NULL 2014-04-08 13:46:32 2014-04-08 14:32:02 NULL na edX/E929/2014_T1
97247 combinedopenended i4x://edX/E929/combinedopenended/90ffcb1647ab4957ab79bec6155bb046 570 {"ready_to_reset": false, "current_task_number": 0, "old_task_states": [], "task_states": ["{\\"child_created\\": false, \\"child_attempts\\": 0, \\"stored_answer\\": null, \\"version\\": 1, \\"child_history\\": [], \\"max_score\\": 2, \\"child_state\\": \\"initial\\"}"], "student_attempts": 0, "state": "assessing"} NULL 2014-04-08 13:46:32 2014-04-08 14:32:04 NULL na edX/E929/2014_T1
97248 combinedopenended i4x://edX/E929/combinedopenended/1c055f72c03641149f2801ea1416ac50 570 {"ready_to_reset": false, "current_task_number": 0, "old_task_states": [], "task_states": ["{\\"child_created\\": false, \\"child_attempts\\": 0, \\"stored_answer\\": null, \\"version\\": 1, \\"child_history\\": [], \\"max_score\\": 2, \\"child_state\\": \\"initial\\"}"], "student_attempts": 0, "state": "assessing"} NULL 2014-04-08 13:46:32 2014-04-08 14:32:02 NULL na edX/E929/2014_T1
97249 sequential i4x://edX/E929/sequential/machine_grading 570 {"position": 4} NULL 2014-04-08 13:46:33 2014-04-08 13:46:39 NULL na edX/E929/2014_T1
97279 chapter i4x://edX/E929/chapter/social_integration 1091 {"position": 2} NULL 2014-04-11 18:50:48 2014-04-11 18:50:48 NULL na edX/E929/2014_T1
97280 sequential i4x://edX/E929/sequential/dbe8fc027bcb4fe9afb744d2e8415855 1091 {"position": 1} NULL 2014-04-11 18:50:48 2014-04-11 18:50:48 NULL na edX/E929/2014_T1
id module_type module_id student_id state grade created modified max_grade done course_id
"""
Run end-to-end acceptance tests. The goal of these tests is to emulate (as closely as possible) user actions and
validate user visible outputs.
"""
from contextlib import closing
import datetime
import json
import logging
import os
import tempfile
import textwrap
import shutil
import subprocess
import urlparse
import boto
import oursql
from edx.analytics.tasks.url import get_target_from_url
from edx.analytics.tasks.url import url_path_join
from edx.analytics.tasks.tests import unittest
log = logging.getLogger(__name__)
class ExportAcceptanceTest(unittest.TestCase):
"""Validate the research data export pipeline for a single course and organization."""
acceptance = 1
ENVIRONMENT = 'acceptance'
TABLE = 'courseware_studentmodule'
NUM_MAPPERS = 4
NUM_REDUCERS = 2
COURSE_ID = 'edX/E929/2014_T1'
def setUp(self):
# These variables will be set later
self.temporary_dir = None
self.data_dir = None
self.external_files_dir = None
self.working_dir = None
self.credentials = None
self.s3_conn = boto.connect_s3()
self.config = json.loads(os.getenv('ACCEPTANCE_TEST_CONFIG'))
self.task_output_root = url_path_join(
self.config.get('tasks_output_url'), self.config.get('identifier'))
# Although this string is semi-arbitrary, in practice we will likely use day of month since it will ensure our
# intermediate data storage doesn't grow without bound while still allowing us to debug old jobs (up to a month
# old).
self.external_prefix = datetime.datetime.utcnow().strftime('%d')
self.output_prefix = 'automation/{ident}/'.format(ident=self.config.get('identifier'))
self.exported_filename = '{safe_course_id}-{table}-{suffix}-analytics.sql'.format(
safe_course_id=self.COURSE_ID.replace('/', '-'),
table=self.TABLE,
suffix=self.ENVIRONMENT,
)
self.org_id = self.COURSE_ID.split('/')[0].lower()
self.load_database_credentials()
self.create_temporary_directories()
def load_database_credentials(self):
"""Retrieve database connection parameters from a URL"""
with get_target_from_url(self.config.get('credentials_file_url')).open('r') as credentials_file:
self.credentials = json.load(credentials_file)
def create_temporary_directories(self):
"""Create temporary local filesystem paths for usage by the test and launched applications."""
self.temporary_dir = tempfile.mkdtemp()
self.addCleanup(shutil.rmtree, self.temporary_dir)
self.data_dir = os.path.join(os.path.dirname(__file__), 'fixtures')
self.external_files_dir = os.path.join(self.temporary_dir, 'external')
self.working_dir = os.path.join(self.temporary_dir, 'work')
for dir_path in [self.external_files_dir, self.working_dir]:
os.makedirs(dir_path)
def test_database_export(self):
# Allow for parallel execution of the test by specifying a different identifier. Using an identical identifier
# allows for old virtualenvs to be reused etc, which is why a random one is not simply generated with each run.
assert('identifier' in self.config)
# Where analytics-tasks should output data, should be a URL pointing to a directory.
assert('tasks_output_url' in self.config)
# A URL to a JSON file that contains connection information for the MySQL database.
assert('credentials_file_url' in self.config)
# The name of an existing job flow to run the test on
assert('job_flow_name' in self.config)
# The branch of the analytics-tasks repository to test. Note this can differ from the branch that is currently
# checked out and running this code.
assert('tasks_branch' in self.config)
# Where to store logs generated by analytics-tasks.
assert('tasks_log_path' in self.config)
# The user to connect to the job flow over SSH with.
assert('connection_user' in self.config)
# An S3 bucket to store the output in.
assert('exporter_output_bucket' in self.config)
self.ensure_database_exists()
self.load_data_from_file()
self.run_export_task()
self.download_task_output()
self.run_legacy_exporter()
self.validate_exporter_output()
def ensure_database_exists(self):
"""Create a testing database on the MySQL if it doesn't exist."""
with self.connect() as conn:
with conn.cursor() as cursor:
cursor.execute('CREATE DATABASE IF NOT EXISTS {0}'.format(self.credentials['database']))
def connect(self, connect_to_database=False):
"""
Connect to the MySQL server.
Arguments:
connect_to_database(bool): Use a database for the connection. Set to false to create databases etc.
"""
kwargs = {
'host': self.credentials['host'],
'user': self.credentials['username'],
'passwd': self.credentials['password'],
}
if connect_to_database:
kwargs['db'] = self.credentials['database']
return closing(oursql.connect(**kwargs))
def load_data_from_file(self):
"""
External Effect: Drops courseware_studentmodule table and loads it with data from a static file.
"""
self.execute_sql_file(os.path.join(self.data_dir, 'input', 'load_{table}.sql'.format(table=self.TABLE)))
def execute_sql_file(self, file_path):
"""
Execute a file containing SQL statements.
Note that this *does not* use MySQL native mechanisms for parsing *.sql files. Instead it very naively parses
the statements out of the file itself.
"""
with self.connect(connect_to_database=True) as conn:
with conn.cursor() as cursor:
with open(file_path, 'r') as sql_file:
for line in sql_file:
if line.startswith('--') or len(line.strip()) == 0:
continue
cursor.execute(line)
def run_export_task(self):
"""
Preconditions: Populated courseware_studentmodule table in the MySQL database.
External Effect: Generates a single text file with the contents of courseware_studentmodule from the MySQL
database for the test course and stores it in S3.
Intermediate output will be stored in s3://<tasks_output_url>/intermediate/. This directory
will contain the complete data set from the MySQL database with all courses interleaved in the data files.
The final output file will be stored in s3://<tasks_output_url>/edX-E929-2014_T1-courseware_studentmodule-acceptance-analytics.sql
"""
command = [
os.getenv('REMOTE_TASK'),
'--job-flow-name', self.config.get('job_flow_name'),
'--branch', self.config.get('tasks_branch'),
'--remote-name', self.config.get('identifier'),
'--wait',
'--log-path', self.config.get('tasks_log_path'),
'--user', self.config.get('connection_user'),
'StudentModulePerCourseAfterImportWorkflow',
'--local-scheduler',
'--credentials', self.config.get('credentials_file_url'),
'--dump-root', url_path_join(self.task_output_root, 'intermediate'),
'--output-root', self.task_output_root,
'--output-suffix', self.ENVIRONMENT,
'--num-mappers', str(self.NUM_MAPPERS),
'--n-reduce-tasks', str(self.NUM_REDUCERS),
]
self.call_subprocess(command)
def call_subprocess(self, command):
"""Execute a subprocess and log the command before running it."""
log.info('Running subprocess {0}'.format(command))
subprocess.check_call(command)
def download_task_output(self):
"""
Preconditions: A single text file for the test course courseware_studentmodule data stored in S3.
External Effect: Downloads the file from S3 and stores it in the external files path. The legacy exporter
can pull externally generated files from that path when it is assembling the complete data package.
Downloads s3://<tasks_output_url>/edX-E929-2014_T1-courseware_studentmodule-acceptance-analytics.sql
and stores it in <temporary_dir>/external/<day of month>/edX-E929-2014_T1-courseware_studentmodule-acceptance-analytics.sql.
"""
parsed_url = urlparse.urlparse(self.task_output_root)
bucket = self.s3_conn.get_bucket(parsed_url.netloc)
key = bucket.lookup(os.path.join(parsed_url.path, self.exported_filename))
if key is None:
self.fail(
'Expected output from StudentModulePerCourseAfterImportWorkflow not found. Url = {0}'.format(
url_path_join(self.task_output_root, self.exported_filename)
)
)
local_dir = os.path.join(self.external_files_dir, self.external_prefix)
os.makedirs(local_dir)
key.get_contents_to_filename(os.path.join(local_dir, self.exported_filename))
def run_legacy_exporter(self):
"""
Preconditions: A text file for courseware_studentmodule has been generated and stored in the external file path.
External Effect: Runs the legacy exporter which assembles the data package, encrypts it, and uploads it to S3.
Reads <temporary_dir>/external/<day of month>/edX-E929-2014_T1-courseware_studentmodule-acceptance-analytics.sql
and copies it in to the data package.
Writes the configuration to <temporary_dir>/acceptance.yml.
Uploads the package to s3://<exporter_output_bucket>/<output_prefix>edx-<year>-<month>-<day>.zip
"""
config_file_path = os.path.join(self.temporary_dir, 'acceptance.yml')
self.write_exporter_config(config_file_path)
# The exporter expects this directory to already exist.
os.makedirs(os.path.join(self.working_dir, 'course-data'))
command = [
os.getenv('EXPORTER'),
'--work-dir', self.working_dir,
'--bucket', self.config.get('exporter_output_bucket'),
'--course-id', self.COURSE_ID,
'--external-prefix', self.external_prefix,
'--output-prefix', self.output_prefix,
config_file_path,
'--env', self.ENVIRONMENT,
'--org', self.org_id,
'--task', 'StudentModuleTask'
]
self.call_subprocess(command)
def write_exporter_config(self, config_file_path):
"""Write out the configuration file that the exporter expects to the filesystem."""
config_text = textwrap.dedent("""\
options: {{}}
defaults:
gpg_keys: gpg-keys
sql_user: {sql_user}
sql_db: {sql_db}
sql_password: {sql_password}
environments:
{environment}:
name: {environment}-analytics
sql_host: {sql_host}
external_files: {external_files}
organizations:
{org_id}:
recipient: daemon@edx.org
""")
config_text = config_text.format(
sql_user=self.credentials['username'],
sql_db=self.credentials['database'],
sql_password=self.credentials['password'],
environment=self.ENVIRONMENT,
sql_host=self.credentials['host'],
external_files=self.external_files_dir,
org_id=self.org_id,
)
with open(config_file_path, 'w') as config_file:
config_file.write(config_text)
def validate_exporter_output(self):
"""
Preconditions: A complete data package has been uploaded to S3.
External Effect: Downloads the complete data package, decompresses it, decrypts it and then compares it to the
static expected output ignoring the ordering of the records in both files.
Downloads s3://<exporter_output_bucket>/<output_prefix>edx-<year>-<month>-<day>.zip to <temporary_dir>/work/validation/.
"""
validation_dir = os.path.join(self.working_dir, 'validation')
os.makedirs(validation_dir)
today = datetime.datetime.utcnow().strftime('%Y-%m-%d')
bucket = self.s3_conn.get_bucket(self.config.get('exporter_output_bucket'))
export_id = '{org}-{date}'.format(org=self.org_id, date=today)
filename = export_id + '.zip'
key = bucket.lookup(self.output_prefix + filename)
if key is None:
self.fail(
'Expected output from legacy exporter not found. Url = s3://{bucket}/{pre}{filename}'.format(
bucket=self.config.get('exporter_output_bucket'),
pre=self.output_prefix,
filename=filename
)
)
exporter_archive_path = os.path.join(validation_dir, filename)
key.get_contents_to_filename(exporter_archive_path)
self.call_subprocess(['unzip', exporter_archive_path, '-d', validation_dir])
gpg_dir = os.path.join(self.working_dir, 'gnupg')
os.makedirs(gpg_dir)
os.chmod(gpg_dir, 0700)
import_key_command = [
'gpg',
'--homedir', gpg_dir,
'--armor',
'--import', 'gpg-keys/insecure_secret.key'
]
self.call_subprocess(import_key_command)
exported_file_path = os.path.join(validation_dir, self.exported_filename)
decrypt_file_command = [
'gpg',
'--homedir', gpg_dir,
'--output', exported_file_path,
'--decrypt', os.path.join(validation_dir, export_id, self.exported_filename + '.gpg'),
]
self.call_subprocess(decrypt_file_command)
sorted_filename = exported_file_path + '.sorted'
self.call_subprocess(['sort', '-o', sorted_filename, exported_file_path])
expected_output_path = os.path.join(self.data_dir, 'output', self.exported_filename + '.sorted')
self.call_subprocess(['diff', sorted_filename, expected_output_path])
-----BEGIN PGP PUBLIC KEY BLOCK-----
Version: GnuPG v1.4.11 (GNU/Linux)
mQENBFNDT/kBCACz8qSn7llbSlOY3OB30jXjw5EWMl8D80jP0fuCC8SyBV+EexOV
uw6z8K2PgGBF7C+rME9fSOP527FTGysaPsJxSedqjreHyn6GF/hzLZwytY3HsVqt
9xJgxZtWHOyjjOqUCtviGpOC71SOYQ7qng3Y026BbNY+9qn//fv++R0UrstSQJuK
nkOo0pWQek4FaNM9DjNvvqyWYpzAw9qaXFRS+UuEIQzjVGRJ/Jo3WaI8DUHR/bvK
kREMmLRKcg6XSZ1oszhuB4HLJJpufZTbSSYZy9dZDSLPtQsr61boCXehjT5AL+Zr
iFIcWb9gJK+HsyP6UpgR/eGHmwuwinasn4zBABEBAAG0TkFjY2VwdGFuY2UgVGVz
dGVyIChJbnNlY3VyZSBrZXkgdXNlZCBmb3IgYWNjZXB0YW5jZSB0ZXN0aW5nLikg
PGRhZW1vbkBlZHgub3JnPokBOAQTAQIAIgUCU0NP+QIbAwYLCQgHAwIGFQgCCQoL
BBYCAwECHgECF4AACgkQSPkLhGSa8tHHMwgAo9YzPVGk1HM9B0iSm0Z97J/8GvtN
AxwGdfnqjebcTHdrovuMDXQENlGSVUC3JsjJTwi84C2XaNejvyS2tLKjiC5Q2OVC
0VW2FAtGmvMh96KZpM635C/obHnm0bIkBjvxR0WuiqZx+6ug5reA9DXd7J8DP6eV
zgRb7Ggb5NYgaCUNO83zQZQFY23dqBhM3tUhFMSCWqykoge+hFUzgvgO4MlYORjJ
dUDvUOxpIFuAeEyKMyUj7nd6JvP4pR+b1sul5edbcdaDzaYiwMRVG/EiWCF/2Dt8
6bWebySDowbeEB2GPbt7zRUHAkcZAxycnlbb9tQ/SrSdMJcAA4iP2mUXvbkBDQRT
Q0/5AQgAuHiCaRHstEPFfpNnMGBHnb102MHrE+Km2aLVXiqnUp1tm5ywiex91Io6
NjZcsBDmebb8Ey8G0D9VMym5Btmm8zTGMJ0mlxUsByFHsmKAlFcRnyRf+PsK8SOT
R2oBDc0b3llm31EkEvS+77vyNS2vYb+ChJ80WBxGybNNLaTPOQVn54W7a80n6SPe
0FS8f1LN6NaMrFBv1GfMM5oSuhkg+ZXzA99WysU9ZYRaTsOgMILhcPd4lpsCennd
efdPgvH6YJH3MBOnvDbayKhUk9wLcx8RbHSdFt8Vskby604ehnQL0Mzde93zY0UJ
V8gktER/87SyJ1t6KfG0ejAQWEEsYQARAQABiQEfBBgBAgAJBQJTQ0/5AhsMAAoJ
EEj5C4RkmvLRSUoH/RXk/PUkf4vLqAHBBQjWMX4hGpstZmRstrCbRbNT0038dvri
oEoJNDG2l372L6td1fhQGpFTjWyswYB1j5+mBLA/VhdMfHczupFt0Few9smeEZ2U
wvfCACEMPOAkvRMw2veUEcy8NDlx/Av2IdazJMn9uVib5zvF/1G/+QYqXLepuUt2
hZB6cKutVQGHbGA5gr5E8el9WTFt9HpK5IwkjzExjbCcAGIOv7YuZNMSm54QxdfJ
JkJPJJvCL7mMkDrz0uHhbKEYAZNYQ4Ah+DgCvMkmWxbK8n3IkPuSg44CNSYyEZYp
QXqGPzBRtWc1sZLgPh75bJmWt5j81CLvbiL5j1I=
=pND5
-----END PGP PUBLIC KEY BLOCK-----
-----BEGIN PGP PRIVATE KEY BLOCK-----
Version: GnuPG v1.4.11 (GNU/Linux)
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
=c43u
-----END PGP PRIVATE KEY BLOCK-----
...@@ -6,4 +6,4 @@ toxworkdir=/tmp/analytics-tox-cache ...@@ -6,4 +6,4 @@ toxworkdir=/tmp/analytics-tox-cache
install_command=pip install --pre --allow-external argparse {opts} {packages} install_command=pip install --pre --allow-external argparse {opts} {packages}
deps=-r{toxinidir}/requirements/default.txt deps=-r{toxinidir}/requirements/default.txt
-r{toxinidir}/requirements/test.txt -r{toxinidir}/requirements/test.txt
commands=nosetests commands=nosetests -A 'not acceptance'
Markdown is supported
0% or
You are about to add 0 people to the discussion. Proceed with caution.
Finish editing this message first!
Please register or to comment