{"action":"created","comment":{"url":"https://api.github.com/repos/in-toto/in-toto/pulls/comments/90261791","pull_request_review_id":10783004,"id":90261791,"diff_hunk":"@@ -0,0 +1,185 @@\n+#!/usr/bin/env python\n+\n+\"\"\"\n+<Program Name>\n+  test_in_toto_record.py\n+\n+<Author>\n+  Lukas Puehringer <lukas.puehringer@nyu.edu>\n+\n+<Started>\n+  Nov 28, 2016\n+\n+<Copyright>\n+  See LICENSE for licensing information.\n+\n+<Purpose>\n+  Test in_toto_record command line tool.\n+\n+\"\"\"\n+\n+import os\n+import sys\n+import unittest\n+import logging\n+import argparse\n+from mock import patch\n+\n+from toto.util import generate_and_write_rsa_keypair\n+from toto.models.link import Link\n+from toto.in_toto_record import main as in_toto_record_main\n+from toto.in_toto_record import in_toto_record_start, in_toto_record_stop\n+\n+# Suppress all the user feedback that we print using a base logger\n+logging.getLogger().setLevel(logging.CRITICAL)\n+\n+def _try_remove_files(file_list):\n+  if not isinstance(file_list, list):\n+    return\n+  else:\n+    for path in file_list:\n+      try:\n+        os.remove(path)\n+      except Exception, e:\n+        pass\n+\n+\n+class TestInTotoRecordMain(unittest.TestCase):\n+  \"\"\"Test in_toto_record's main() - requires sys.argv patching. \"\"\"\n+\n+  @classmethod\n+  def setUpClass(self):\n+    \"\"\"Generate key pair, dummy artifact and base arguments. \"\"\"\n+    generate_and_write_rsa_keypair(\"test-key\")\n+    self.args = [\n+        \"in_toto_record.py\",\n+        \"--step-name\",\n+        \"test-step\",\n+        \"--key\",\n+        \"test-key\"\n+    ]\n+    self.test_artifact = \"test-artifact\"\n+    open(self.test_artifact, \"a\").close()\n+\n+  @classmethod\n+  def tearDownClass(self):\n+    \"\"\"Remove key pair, dummy artifact and link metadata. \"\"\"\n+    files_to_remove = [\n+      \"test-key\", \"test-key.pub\", \"test-step.link\", self.test_artifact\n+    ]\n+    _try_remove_files(files_to_remove)\n+\n+\n+  def test_command_start_stop_required_args(self):\n+    \"\"\"Test CLI command record start/stop with required arguments. \"\"\"\n+    with patch.object(sys, 'argv',  self.args + [\"start\"]):\n+      in_toto_record_main()\n+\n+    with patch.object(sys, 'argv', self.args + [\"stop\"]):\n+      in_toto_record_main()\n+\n+  def test_command_start_stop_optional_args(self):\n+    \"\"\"Test CLI command record start/stop with optional arguments. \"\"\"\n+    with patch.object(sys, 'argv', self.args + [\"start\", \"--materials\",\n+        self.test_artifact]):\n+      in_toto_record_main()\n+\n+    with patch.object(sys, 'argv', self.args + [\"stop\", \"--products\",\n+        self.test_artifact]):\n+      in_toto_record_main()\n+\n+\n+\n+\n+\n+class TestInTotoRecordStart(unittest.TestCase):\n+  \"\"\"\"Test in_toto_record_start(step_name, key_path, material_list). \"\"\"\n+\n+  @classmethod\n+  def setUpClass(self):\n+    \"\"\"Generate key pair, dummy artifact and base arguments. \"\"\"\n+    self.step_name = \"test-step\"\n+    self.key_path = \"test-key\"\n+    generate_and_write_rsa_keypair(self.key_path)\n+    self.test_material= \"test-material\"\n+    open(self.test_material, \"a\").close()\n+\n+  @classmethod\n+  def tearDownClass(self):\n+    \"\"\"Remove key pair, dummy artifact and link metadata. \"\"\"\n+    files_to_remove = [\n+        self.key_path, self.key_path + \".pub\", self.test_material,\n+        \".\" + self.step_name + \".link-unfinished\"\n+      ]\n+    _try_remove_files(files_to_remove)\n+\n+  def test_create_link_unfinished_file(self):\n+    \"\"\"Test record start creates a link metadata file. \"\"\"\n+    in_toto_record_start(self.step_name, self.key_path, [self.test_material])\n+    open(\".\" + self.step_name + \".link-unfinished\", \"r\")\n+\n+  def test_record_test_material(self):\n+    \"\"\"Test record start records expected material. \"\"\"\n+    link = in_toto_record_start(\n+        self.step_name, self.key_path, [self.test_material])\n+    self.assertEquals(link.materials.keys(), [self.test_material])\n+\n+\n+\n+\n+\n+class TestInTotoRecordStop(unittest.TestCase):\n+  \"\"\"\"Test in_toto_record_start(step_name, key_path, material_list). \"\"\"\n+\n+  @classmethod\n+  def setUpClass(self):\n+    \"\"\"Generate key pair, dummy artifact and base arguments. \"\"\"\n+    self.step_name = \"test-step\"\n+    self.key_path = \"test-key\"\n+    self.key_path2 = \"test-key2\"\n+    generate_and_write_rsa_keypair(self.key_path)\n+    generate_and_write_rsa_keypair(self.key_path)\n+\n+    self.test_product = \"test-product\"\n+    open(self.test_product, \"a\").close()","path":"test/test_in_toto_record.py","position":144,"original_position":144,"commit_id":"e4e47cfb97ab9fad3850a31be5a4290f9effbd2f","original_commit_id":"e4e47cfb97ab9fad3850a31be5a4290f9effbd2f","user":{"login":"lukpueh","id":589324,"avatar_url":"https://avatars.githubusercontent.com/u/589324?v=3","gravatar_id":"","url":"https://api.github.com/users/lukpueh","html_url":"https://github.com/lukpueh","followers_url":"https://api.github.com/users/lukpueh/followers","following_url":"https://api.github.com/users/lukpueh/following{/other_user}","gists_url":"https://api.github.com/users/lukpueh/gists{/gist_id}","starred_url":"https://api.github.com/users/lukpueh/starred{/owner}{/repo}","subscriptions_url":"https://api.github.com/users/lukpueh/subscriptions","organizations_url":"https://api.github.com/users/lukpueh/orgs","repos_url":"https://api.github.com/users/lukpueh/repos","events_url":"https://api.github.com/users/lukpueh/events{/privacy}","received_events_url":"https://api.github.com/users/lukpueh/received_events","type":"User","site_admin":false},"body":"No reason. Will change to `w`","created_at":"2016-11-30T15:55:13Z","updated_at":"2016-11-30T15:55:13Z","html_url":"https://github.com/in-toto/in-toto/pull/52#discussion_r90261791","pull_request_url":"https://api.github.com/repos/in-toto/in-toto/pulls/52","_links":{"self":{"href":"https://api.github.com/repos/in-toto/in-toto/pulls/comments/90261791"},"html":{"href":"https://github.com/in-toto/in-toto/pull/52#discussion_r90261791"},"pull_request":{"href":"https://api.github.com/repos/in-toto/in-toto/pulls/52"}}},"pull_request":{"url":"https://api.github.com/repos/in-toto/in-toto/pulls/52","id":95780367,"html_url":"https://github.com/in-toto/in-toto/pull/52","diff_url":"https://github.com/in-toto/in-toto/pull/52.diff","patch_url":"https://github.com/in-toto/in-toto/pull/52.patch","issue_url":"https://api.github.com/repos/in-toto/in-toto/issues/52","number":52,"state":"open","locked":false,"title":"Adds in_toto_record {start, stop} command + minor changes/fixes","user":{"login":"lukpueh","id":589324,"avatar_url":"https://avatars.githubusercontent.com/u/589324?v=3","gravatar_id":"","url":"https://api.github.com/users/lukpueh","html_url":"https://github.com/lukpueh","followers_url":"https://api.github.com/users/lukpueh/followers","following_url":"https://api.github.com/users/lukpueh/following{/other_user}","gists_url":"https://api.github.com/users/lukpueh/gists{/gist_id}","starred_url":"https://api.github.com/users/lukpueh/starred{/owner}{/repo}","subscriptions_url":"https://api.github.com/users/lukpueh/subscriptions","organizations_url":"https://api.github.com/users/lukpueh/orgs","repos_url":"https://api.github.com/users/lukpueh/repos","events_url":"https://api.github.com/users/lukpueh/events{/privacy}","received_events_url":"https://api.github.com/users/lukpueh/received_events","type":"User","site_admin":false},"body":"In some cases it is not feasible to wrap a single command with toto-run, e.g. when allowedly editing a bunch of files shortly before building.\r\nTo not disrupt the in-toto supply chain we provide two additional cli tools that, where one only records materials to a temporary file and the second records products and finalizes the link metadata file.\r\n\r\n- Adds new command line tool (with two sub commands) to perform a multi-part in-toto step\r\n- Adds unittests for in_toto_record start/stop (requires `mock` package)\r\n- Adds default values to optional parameters of runlib.create_link_metadata\r\n- Changes `attr` class attribute defaults to use `attr.Factory` in order to circumvent strange memory re-use (see. https://github.com/in-toto/in-toto/commit/be7619173e13cbfb17093ac945a16083eb3d12db commit message for more details).\r\n- Fixes wrong default type for `layout.keys` attributes (https://github.com/in-toto/in-toto/issues/41)\r\n- Removes two obsolete utility classes:  \r\n - `GenericPathList` \r\nwas used to *normalize* relative artifact paths at verification, which now happens at recording \r\n - `ComparableHashDict`\r\nwas used to compare artifact hashes with multiple hash algorithms, deprecated by `util.flatten_and_invert_artifact_dict`","created_at":"2016-11-29T21:35:40Z","updated_at":"2016-11-30T15:55:13Z","closed_at":null,"merged_at":null,"merge_commit_sha":"91276f938f3338863902103de33495d224cd348e","assignee":null,"assignees":[],"milestone":null,"commits_url":"https://api.github.com/repos/in-toto/in-toto/pulls/52/commits","review_comments_url":"https://api.github.com/repos/in-toto/in-toto/pulls/52/comments","review_comment_url":"https://api.github.com/repos/in-toto/in-toto/pulls/comments{/number}","comments_url":"https://api.github.com/repos/in-toto/in-toto/issues/52/comments","statuses_url":"https://api.github.com/repos/in-toto/in-toto/statuses/e4e47cfb97ab9fad3850a31be5a4290f9effbd2f","head":{"label":"in-toto:record-start-stop","ref":"record-start-stop","sha":"e4e47cfb97ab9fad3850a31be5a4290f9effbd2f","user":{"login":"in-toto","id":22891761,"avatar_url":"https://avatars.githubusercontent.com/u/22891761?v=3","gravatar_id":"","url":"https://api.github.com/users/in-toto","html_url":"https://github.com/in-toto","followers_url":"https://api.github.com/users/in-toto/followers","following_url":"https://api.github.com/users/in-toto/following{/other_user}","gists_url":"https://api.github.com/users/in-toto/gists{/gist_id}","starred_url":"https://api.github.com/users/in-toto/starred{/owner}{/repo}","subscriptions_url":"https://api.github.com/users/in-toto/subscriptions","organizations_url":"https://api.github.com/users/in-toto/orgs","repos_url":"https://api.github.com/users/in-toto/repos","events_url":"https://api.github.com/users/in-toto/events{/privacy}","received_events_url":"https://api.github.com/users/in-toto/received_events","type":"Organization","site_admin":false},"repo":{"id":59531400,"name":"in-toto","full_name":"in-toto/in-toto","owner":{"login":"in-toto","id":22891761,"avatar_url":"https://avatars.githubusercontent.com/u/22891761?v=3","gravatar_id":"","url":"https://api.github.com/users/in-toto","html_url":"https://github.com/in-toto","followers_url":"https://api.github.com/users/in-toto/followers","following_url":"https://api.github.com/users/in-toto/following{/other_user}","gists_url":"https://api.github.com/users/in-toto/gists{/gist_id}","starred_url":"https://api.github.com/users/in-toto/starred{/owner}{/repo}","subscriptions_url":"https://api.github.com/users/in-toto/subscriptions","organizations_url":"https://api.github.com/users/in-toto/orgs","repos_url":"https://api.github.com/users/in-toto/repos","events_url":"https://api.github.com/users/in-toto/events{/privacy}","received_events_url":"https://api.github.com/users/in-toto/received_events","type":"Organization","site_admin":false},"private":false,"html_url":"https://github.com/in-toto/in-toto","description":"Toto is a framework to protect supply chain integrity.","fork":false,"url":"https://api.github.com/repos/in-toto/in-toto","forks_url":"https://api.github.com/repos/in-toto/in-toto/forks","keys_url":"https://api.github.com/repos/in-toto/in-toto/keys{/key_id}","collaborators_url":"https://api.github.com/repos/in-toto/in-toto/collaborators{/collaborator}","teams_url":"https://api.github.com/repos/in-toto/in-toto/teams","hooks_url":"https://api.github.com/repos/in-toto/in-toto/hooks","issue_events_url":"https://api.github.com/repos/in-toto/in-toto/issues/events{/number}","events_url":"https://api.github.com/repos/in-toto/in-toto/events","assignees_url":"https://api.github.com/repos/in-toto/in-toto/assignees{/user}","branches_url":"https://api.github.com/repos/in-toto/in-toto/branches{/branch}","tags_url":"https://api.github.com/repos/in-toto/in-toto/tags","blobs_url":"https://api.github.com/repos/in-toto/in-toto/git/blobs{/sha}","git_tags_url":"https://api.github.com/repos/in-toto/in-toto/git/tags{/sha}","git_refs_url":"https://api.github.com/repos/in-toto/in-toto/git/refs{/sha}","trees_url":"https://api.github.com/repos/in-toto/in-toto/git/trees{/sha}","statuses_url":"https://api.github.com/repos/in-toto/in-toto/statuses/{sha}","languages_url":"https://api.github.com/repos/in-toto/in-toto/languages","stargazers_url":"https://api.github.com/repos/in-toto/in-toto/stargazers","contributors_url":"https://api.github.com/repos/in-toto/in-toto/contributors","subscribers_url":"https://api.github.com/repos/in-toto/in-toto/subscribers","subscription_url":"https://api.github.com/repos/in-toto/in-toto/subscription","commits_url":"https://api.github.com/repos/in-toto/in-toto/commits{/sha}","git_commits_url":"https://api.github.com/repos/in-toto/in-toto/git/commits{/sha}","comments_url":"https://api.github.com/repos/in-toto/in-toto/comments{/number}","issue_comment_url":"https://api.github.com/repos/in-toto/in-toto/issues/comments{/number}","contents_url":"https://api.github.com/repos/in-toto/in-toto/contents/{+path}","compare_url":"https://api.github.com/repos/in-toto/in-toto/compare/{base}...{head}","merges_url":"https://api.github.com/repos/in-toto/in-toto/merges","archive_url":"https://api.github.com/repos/in-toto/in-toto/{archive_format}{/ref}","downloads_url":"https://api.github.com/repos/in-toto/in-toto/downloads","issues_url":"https://api.github.com/repos/in-toto/in-toto/issues{/number}","pulls_url":"https://api.github.com/repos/in-toto/in-toto/pulls{/number}","milestones_url":"https://api.github.com/repos/in-toto/in-toto/milestones{/number}","notifications_url":"https://api.github.com/repos/in-toto/in-toto/notifications{?since,all,participating}","labels_url":"https://api.github.com/repos/in-toto/in-toto/labels{/name}","releases_url":"https://api.github.com/repos/in-toto/in-toto/releases{/id}","deployments_url":"https://api.github.com/repos/in-toto/in-toto/deployments","created_at":"2016-05-24T01:46:38Z","updated_at":"2016-10-28T16:54:56Z","pushed_at":"2016-11-29T23:34:48Z","git_url":"git://github.com/in-toto/in-toto.git","ssh_url":"git@github.com:in-toto/in-toto.git","clone_url":"https://github.com/in-toto/in-toto.git","svn_url":"https://github.com/in-toto/in-toto","homepage":"","size":355,"stargazers_count":1,"watchers_count":1,"language":"Python","has_issues":true,"has_downloads":true,"has_wiki":true,"has_pages":false,"forks_count":7,"mirror_url":null,"open_issues_count":24,"forks":7,"open_issues":24,"watchers":1,"default_branch":"develop"}},"base":{"label":"in-toto:develop","ref":"develop","sha":"789dd2ecbbefe521bd5cf550374dada654b313b7","user":{"login":"in-toto","id":22891761,"avatar_url":"https://avatars.githubusercontent.com/u/22891761?v=3","gravatar_id":"","url":"https://api.github.com/users/in-toto","html_url":"https://github.com/in-toto","followers_url":"https://api.github.com/users/in-toto/followers","following_url":"https://api.github.com/users/in-toto/following{/other_user}","gists_url":"https://api.github.com/users/in-toto/gists{/gist_id}","starred_url":"https://api.github.com/users/in-toto/starred{/owner}{/repo}","subscriptions_url":"https://api.github.com/users/in-toto/subscriptions","organizations_url":"https://api.github.com/users/in-toto/orgs","repos_url":"https://api.github.com/users/in-toto/repos","events_url":"https://api.github.com/users/in-toto/events{/privacy}","received_events_url":"https://api.github.com/users/in-toto/received_events","type":"Organization","site_admin":false},"repo":{"id":59531400,"name":"in-toto","full_name":"in-toto/in-toto","owner":{"login":"in-toto","id":22891761,"avatar_url":"https://avatars.githubusercontent.com/u/22891761?v=3","gravatar_id":"","url":"https://api.github.com/users/in-toto","html_url":"https://github.com/in-toto","followers_url":"https://api.github.com/users/in-toto/followers","following_url":"https://api.github.com/users/in-toto/following{/other_user}","gists_url":"https://api.github.com/users/in-toto/gists{/gist_id}","starred_url":"https://api.github.com/users/in-toto/starred{/owner}{/repo}","subscriptions_url":"https://api.github.com/users/in-toto/subscriptions","organizations_url":"https://api.github.com/users/in-toto/orgs","repos_url":"https://api.github.com/users/in-toto/repos","events_url":"https://api.github.com/users/in-toto/events{/privacy}","received_events_url":"https://api.github.com/users/in-toto/received_events","type":"Organization","site_admin":false},"private":false,"html_url":"https://github.com/in-toto/in-toto","description":"Toto is a framework to protect supply chain integrity.","fork":false,"url":"https://api.github.com/repos/in-toto/in-toto","forks_url":"https://api.github.com/repos/in-toto/in-toto/forks","keys_url":"https://api.github.com/repos/in-toto/in-toto/keys{/key_id}","collaborators_url":"https://api.github.com/repos/in-toto/in-toto/collaborators{/collaborator}","teams_url":"https://api.github.com/repos/in-toto/in-toto/teams","hooks_url":"https://api.github.com/repos/in-toto/in-toto/hooks","issue_events_url":"https://api.github.com/repos/in-toto/in-toto/issues/events{/number}","events_url":"https://api.github.com/repos/in-toto/in-toto/events","assignees_url":"https://api.github.com/repos/in-toto/in-toto/assignees{/user}","branches_url":"https://api.github.com/repos/in-toto/in-toto/branches{/branch}","tags_url":"https://api.github.com/repos/in-toto/in-toto/tags","blobs_url":"https://api.github.com/repos/in-toto/in-toto/git/blobs{/sha}","git_tags_url":"https://api.github.com/repos/in-toto/in-toto/git/tags{/sha}","git_refs_url":"https://api.github.com/repos/in-toto/in-toto/git/refs{/sha}","trees_url":"https://api.github.com/repos/in-toto/in-toto/git/trees{/sha}","statuses_url":"https://api.github.com/repos/in-toto/in-toto/statuses/{sha}","languages_url":"https://api.github.com/repos/in-toto/in-toto/languages","stargazers_url":"https://api.github.com/repos/in-toto/in-toto/stargazers","contributors_url":"https://api.github.com/repos/in-toto/in-toto/contributors","subscribers_url":"https://api.github.com/repos/in-toto/in-toto/subscribers","subscription_url":"https://api.github.com/repos/in-toto/in-toto/subscription","commits_url":"https://api.github.com/repos/in-toto/in-toto/commits{/sha}","git_commits_url":"https://api.github.com/repos/in-toto/in-toto/git/commits{/sha}","comments_url":"https://api.github.com/repos/in-toto/in-toto/comments{/number}","issue_comment_url":"https://api.github.com/repos/in-toto/in-toto/issues/comments{/number}","contents_url":"https://api.github.com/repos/in-toto/in-toto/contents/{+path}","compare_url":"https://api.github.com/repos/in-toto/in-toto/compare/{base}...{head}","merges_url":"https://api.github.com/repos/in-toto/in-toto/merges","archive_url":"https://api.github.com/repos/in-toto/in-toto/{archive_format}{/ref}","downloads_url":"https://api.github.com/repos/in-toto/in-toto/downloads","issues_url":"https://api.github.com/repos/in-toto/in-toto/issues{/number}","pulls_url":"https://api.github.com/repos/in-toto/in-toto/pulls{/number}","milestones_url":"https://api.github.com/repos/in-toto/in-toto/milestones{/number}","notifications_url":"https://api.github.com/repos/in-toto/in-toto/notifications{?since,all,participating}","labels_url":"https://api.github.com/repos/in-toto/in-toto/labels{/name}","releases_url":"https://api.github.com/repos/in-toto/in-toto/releases{/id}","deployments_url":"https://api.github.com/repos/in-toto/in-toto/deployments","created_at":"2016-05-24T01:46:38Z","updated_at":"2016-10-28T16:54:56Z","pushed_at":"2016-11-29T23:34:48Z","git_url":"git://github.com/in-toto/in-toto.git","ssh_url":"git@github.com:in-toto/in-toto.git","clone_url":"https://github.com/in-toto/in-toto.git","svn_url":"https://github.com/in-toto/in-toto","homepage":"","size":355,"stargazers_count":1,"watchers_count":1,"language":"Python","has_issues":true,"has_downloads":true,"has_wiki":true,"has_pages":false,"forks_count":7,"mirror_url":null,"open_issues_count":24,"forks":7,"open_issues":24,"watchers":1,"default_branch":"develop"}},"_links":{"self":{"href":"https://api.github.com/repos/in-toto/in-toto/pulls/52"},"html":{"href":"https://github.com/in-toto/in-toto/pull/52"},"issue":{"href":"https://api.github.com/repos/in-toto/in-toto/issues/52"},"comments":{"href":"https://api.github.com/repos/in-toto/in-toto/issues/52/comments"},"review_comments":{"href":"https://api.github.com/repos/in-toto/in-toto/pulls/52/comments"},"review_comment":{"href":"https://api.github.com/repos/in-toto/in-toto/pulls/comments{/number}"},"commits":{"href":"https://api.github.com/repos/in-toto/in-toto/pulls/52/commits"},"statuses":{"href":"https://api.github.com/repos/in-toto/in-toto/statuses/e4e47cfb97ab9fad3850a31be5a4290f9effbd2f"}}}}
{"actor":{"display_login":"lukpueh"}}