Пример #1
0
    def create_activity_record(self, record: ActivityRecord) -> ActivityRecord:
        """Method to write an activity record and its details to the git log and detaildb

        Args:
            record(ActivityRecord): A populated activity record

        Returns:
            ActivityRecord
        """
        # If there isn't a linked commit, generate a UUID to uniquely ID the data in levelDB that will never
        # collide with the actual git hash space by making it 32 char vs. 40 for git
        if not record.linked_commit:
            record.linked_commit = uuid.uuid4().hex

        # Write all ActivityDetailObjects to the datastore
        with record.inspect_detail_objects() as details:
            for idx, detail in enumerate(details):
                updated_detail = self.put_detail_record(detail)
                record.update_detail_object(updated_detail, idx)

        # Add everything in the repo activity/log directory
        self.repository.git.add_all(self.detaildb.root_path)

        # Commit changes and update record
        commit = self.repository.git.commit(record.log_str)
        record.commit = commit.hexsha

        # Update record with username and email
        record.username = self.repository.git.author.name
        record.email = self.repository.git.author.email

        logger.debug(f"Successfully created ActivityRecord {commit.hexsha}")
        return record
Пример #2
0
    def test_add_detail_object(self):
        """Test adding values to the detail object"""
        ar = ActivityRecord(ActivityType.CODE,
                            show=True,
                            message="added some code",
                            importance=50,
                            linked_commit='aaaaaaaa')

        adr = ActivityDetailRecord(ActivityDetailType.CODE)
        adr.add_value("text/plain", "this is some data")

        ar.add_detail_object(adr)

        assert len(ar._detail_objects) == 1
        assert ar._detail_objects[0][0] is True
        assert ar._detail_objects[0][1] == ActivityDetailType.CODE.value
        assert ar._detail_objects[0][2] == 0
        assert ar._detail_objects[0][3] == adr
Пример #3
0
    def get_activity_record(self, commit: str) -> ActivityRecord:
        """Method to get a single ActivityRecord

        Args:
            commit(str): The commit hash of the activity record

        Returns:
            ActivityRecord
        """
        entry = self.repository.git.log_entry(commit)
        m = self.note_regex.match(entry["message"])
        if m:
            ar = ActivityRecord.from_log_str(m.group(0),
                                             commit,
                                             entry['committed_on'],
                                             username=entry['author']['name'],
                                             email=entry['author']['email'])
            return ar
        else:
            raise ValueError(
                "Activity data not found in commit {}".format(commit))
Пример #4
0
    def test_from_log_str(self):
        """Test the creating from a log string"""

        test_str = """_GTM_ACTIVITY_START_**
msg:added some code**
metadata:{"show":true,"importance":50,"type":2,"linked_commit":"aaaaaaaa","tags":["test"]}**
details:**
4,1,255,my_fake_detail_key,0**
2,0,0,my_fake_detail_key2,3**
_GTM_ACTIVITY_END_"""

        ar = ActivityRecord.from_log_str(test_str, "bbbbbb",
                                         datetime.datetime.utcnow())

        assert type(ar) == ActivityRecord
        assert ar.type == ActivityType.CODE
        assert ar.show is True
        assert ar.importance == 50
        assert ar.linked_commit == "aaaaaaaa"
        assert ar.commit == "bbbbbb"
        assert ar.tags == ['test']

        assert len(ar._detail_objects) == 2
        assert type(ar._detail_objects[0][3]) == ActivityDetailRecord
        assert ar._detail_objects[0][3].type == ActivityDetailType.CODE
        assert ar._detail_objects[0][3].action == ActivityAction.NOACTION
        assert ar._detail_objects[0][3].key == "my_fake_detail_key"
        assert ar._detail_objects[0][3].show is True
        assert ar._detail_objects[0][3].importance == 255
        assert ar._detail_objects[0][3].tags == []
        assert ar._detail_objects[0][3].is_loaded is False

        assert type(ar._detail_objects[1][3]) == ActivityDetailRecord
        assert ar._detail_objects[1][3].type == ActivityDetailType.RESULT
        assert ar._detail_objects[1][3].action == ActivityAction.DELETE
        assert ar._detail_objects[1][3].key == "my_fake_detail_key2"
        assert ar._detail_objects[1][3].show is False
        assert ar._detail_objects[1][3].importance == 0
        assert ar._detail_objects[1][3].tags == []
        assert ar._detail_objects[1][3].is_loaded is False
Пример #5
0
    def get_activity_records(
            self,
            after: Optional[str] = None,
            first: Optional[int] = None) -> List[Optional[ActivityRecord]]:
        """Method to get a list of activity records, with forward paging supported

        Args:
            after(str): Commit hash to page after
            first(int): Number of records to get

        Returns:
            List[ActivityRecord]
        """
        # Get data from the git log
        log_data = self._get_log_records(after=after, first=first)
        if log_data:
            if after:
                # If the "after" record is included. Remove it due to standards on how relay paging works
                log_data = log_data[1:]

            # If first value provided, check for the right amount of data
            if first:
                if len(log_data) > first:
                    # Need to prune due to padding sent into self._get_log_records()
                    log_data = log_data[:first]

        if log_data:
            return [
                ActivityRecord.from_log_str(x[0],
                                            x[1],
                                            x[2],
                                            username=x[3],
                                            email=x[4]) for x in log_data
            ]
        else:
            return []
Пример #6
0
    def test_log_str_prop_errors(self):
        """Test the log string property"""
        ar = ActivityRecord(ActivityType.CODE,
                            show=True,
                            importance=50,
                            linked_commit='aaaaaaaa')

        with pytest.raises(ValueError):
            # Missing message
            _ = ar.log_str

        ar = ActivityRecord(ActivityType.CODE,
                            show=True,
                            message="added some code",
                            importance=50,
                            linked_commit='aaaaaaaa')

        adr = ActivityDetailRecord(ActivityDetailType.CODE)
        adr.add_value("text/plain", "this is some data")
        ar.add_detail_object(adr)

        with pytest.raises(ValueError):
            # Missing detail key for detail record
            ar.log_str
Пример #7
0
    def test_add_detail_objects_sort(self):
        """Test adding values to the detail object"""
        ar = ActivityRecord(ActivityType.CODE,
                            show=True,
                            message="added some code",
                            importance=50,
                            linked_commit='aaaaaaaa')

        adr = ActivityDetailRecord(ActivityDetailType.CODE)
        adr.show = True
        adr.importance = 100
        adr.add_value("text/plain", "second")
        ar.add_detail_object(adr)

        adr = ActivityDetailRecord(ActivityDetailType.CODE)
        adr.show = True
        adr.importance = 200
        adr.add_value("text/plain", "first")
        ar.add_detail_object(adr)

        adr = ActivityDetailRecord(ActivityDetailType.CODE)
        adr.show = False
        adr.importance = 0
        adr.add_value("text/plain", "sixth")
        ar.add_detail_object(adr)

        adr = ActivityDetailRecord(ActivityDetailType.OUTPUT_DATA)
        adr.show = True
        adr.importance = 201
        adr.add_value("text/plain", "forth")
        ar.add_detail_object(adr)

        adr = ActivityDetailRecord(ActivityDetailType.RESULT)
        adr.show = True
        adr.importance = 201
        adr.add_value("text/plain", "third")
        ar.add_detail_object(adr)

        adr = ActivityDetailRecord(ActivityDetailType.INPUT_DATA)
        adr.show = False
        adr.importance = 201
        adr.add_value("text/plain", "fifth")
        ar.add_detail_object(adr)

        assert len(ar._detail_objects) == 6

        assert ar._detail_objects[0][3].data['text/plain'] == 'first'
        assert ar._detail_objects[1][3].data['text/plain'] == 'second'
        assert ar._detail_objects[2][3].data['text/plain'] == 'third'
        assert ar._detail_objects[3][3].data['text/plain'] == 'forth'
        assert ar._detail_objects[4][3].data['text/plain'] == 'fifth'
        assert ar._detail_objects[5][3].data['text/plain'] == 'sixth'
Пример #8
0
    def test_trim_detail_objects(self):
        """"""
        ar = ActivityRecord(ActivityType.CODE,
                            show=True,
                            message="added some code",
                            importance=50,
                            linked_commit='aaaaaaaa')

        adr1 = ActivityDetailRecord(ActivityDetailType.CODE)
        adr1.show = True
        adr1.importance = 100
        adr1.add_value("text/plain", "first")
        ar.add_detail_object(adr1)

        adr2 = ActivityDetailRecord(ActivityDetailType.CODE)
        adr2.show = True
        adr2.importance = 0
        adr2.add_value("text/plain", "second")
        ar.add_detail_object(adr2)

        adr3 = ActivityDetailRecord(ActivityDetailType.CODE)
        adr3.show = True
        adr3.importance = 0
        adr3.add_value("text/plain", "third")
        ar.add_detail_object(adr3)

        assert len(ar._detail_objects) == 3
        assert ar._detail_objects[0][3].data['text/plain'] == 'first'
        assert ar._detail_objects[1][3].data['text/plain'] == 'second'
        assert ar._detail_objects[2][3].data['text/plain'] == 'third'

        with ar.inspect_detail_objects():
            ar.trim_detail_objects(2)

        assert len(ar._detail_objects) == 2
        assert ar._detail_objects[0][3].data['text/plain'] == 'first'
        assert ar._detail_objects[1][3].data['text/plain'] == 'second'

        with pytest.raises(ValueError):
            with ar.inspect_detail_objects():
                ar.trim_detail_objects(0)
Пример #9
0
    def test_get_activity_records_with_intermediate_commits(self, mock_config_with_activitystore):
        """Method to test creating and getting a bunch of activity records with intermediate commits made"""

        linked_commit = helper_create_labbook_change(mock_config_with_activitystore[1], 1)

        ar = ActivityRecord(ActivityType.CODE,
                            show=True,
                            message="added some code 1",
                            importance=50,
                            linked_commit=linked_commit.hexsha)

        record1 = mock_config_with_activitystore[0].create_activity_record(ar)

        # Add some intermediate commits
        for cnt in range(10):
            helper_create_labbook_change(mock_config_with_activitystore[1], cnt)

        linked_commit = helper_create_labbook_change(mock_config_with_activitystore[1], 1)

        ar = ActivityRecord(ActivityType.CODE,
                            show=True,
                            message="added some code 2",
                            importance=50,
                            linked_commit=linked_commit.hexsha)

        record2 = mock_config_with_activitystore[0].create_activity_record(ar)

        linked_commit = helper_create_labbook_change(mock_config_with_activitystore[1], 1)

        ar = ActivityRecord(ActivityType.CODE,
                            show=True,
                            message="added some code 3",
                            importance=50,
                            linked_commit=linked_commit.hexsha)

        record3 = mock_config_with_activitystore[0].create_activity_record(ar)

        # add a bunch of non-activity record commits, which previously would prevent activity from coming back
        for cnt in range(20):
            helper_create_labbook_change(mock_config_with_activitystore[1], cnt)

        activity_records = mock_config_with_activitystore[0].get_activity_records()
        assert len(activity_records) == 3
        assert activity_records[0].commit == record3.commit
        assert activity_records[0].linked_commit == record3.linked_commit
        assert activity_records[0].message == record3.message
        assert activity_records[1].commit == record2.commit
        assert activity_records[1].linked_commit == record2.linked_commit
        assert activity_records[1].message == record2.message
        assert activity_records[2].commit == record1.commit
        assert activity_records[2].linked_commit == record1.linked_commit
        assert activity_records[2].message == record1.message
        assert activity_records[2].username == 'default'
        assert activity_records[2].email == '*****@*****.**'

        activity_records = mock_config_with_activitystore[0].get_activity_records(first=6)
        assert len(activity_records) == 3
        assert activity_records[0].commit == record3.commit
        assert activity_records[0].linked_commit == record3.linked_commit
        assert activity_records[0].message == record3.message
        assert activity_records[1].commit == record2.commit
        assert activity_records[1].linked_commit == record2.linked_commit
        assert activity_records[1].message == record2.message
        assert activity_records[2].commit == record1.commit
        assert activity_records[2].linked_commit == record1.linked_commit
        assert activity_records[2].message == record1.message
        assert activity_records[2].username == 'default'
        assert activity_records[2].email == '*****@*****.**'

        activity_records = mock_config_with_activitystore[0].get_activity_records(first=20)
        assert len(activity_records) == 3

        activity_records = mock_config_with_activitystore[0].get_activity_records(first=2)
        assert len(activity_records) == 2

        # Verify the timestamp is getting set properly
        assert type(activity_records[0].timestamp) == datetime
        assert activity_records[0].timestamp < datetime.now(timezone.utc)
        assert activity_records[0].timestamp > datetime.now(timezone.utc) - timedelta(seconds=10)

        activity_records = mock_config_with_activitystore[0].get_activity_records(first=1)
        assert len(activity_records) == 1
        assert activity_records[0].commit == record3.commit
        assert activity_records[0].linked_commit == record3.linked_commit
        assert activity_records[0].message == record3.message

        activity_records = mock_config_with_activitystore[0].get_activity_records(after=record2.commit)
        assert len(activity_records) == 1
        assert activity_records[0].commit == record1.commit
        assert activity_records[0].linked_commit == record1.linked_commit
        assert activity_records[0].message == record1.message

        activity_records = mock_config_with_activitystore[0].get_activity_records(after=record3.commit, first=1)
        assert len(activity_records) == 1
        assert activity_records[0].commit == record2.commit
        assert activity_records[0].linked_commit == record2.linked_commit
        assert activity_records[0].message == record2.message

        activity_records = mock_config_with_activitystore[0].get_activity_records(after=record3.commit, first=20)
        assert len(activity_records) == 2
        assert activity_records[0].commit == record2.commit
        assert activity_records[0].linked_commit == record2.linked_commit
        assert activity_records[0].message == record2.message
Пример #10
0
    def test_get_activity_records(self, mock_config_with_activitystore):
        """Method to test creating and getting a bunch of activity records"""

        linked_commit = helper_create_labbook_change(mock_config_with_activitystore[1], 1)

        ar = ActivityRecord(ActivityType.CODE,
                            show=True,
                            message="added some code 1",
                            importance=50,
                            linked_commit=linked_commit.hexsha)

        record1 = mock_config_with_activitystore[0].create_activity_record(ar)

        linked_commit = helper_create_labbook_change(mock_config_with_activitystore[1], 1)

        ar = ActivityRecord(ActivityType.CODE,
                            show=True,
                            message="added some code 2",
                            importance=50,
                            linked_commit=linked_commit.hexsha)

        record2 = mock_config_with_activitystore[0].create_activity_record(ar)

        linked_commit = helper_create_labbook_change(mock_config_with_activitystore[1], 1)

        ar = ActivityRecord(ActivityType.CODE,
                            show=True,
                            message="added some code 3",
                            importance=50,
                            linked_commit=linked_commit.hexsha)

        record3 = mock_config_with_activitystore[0].create_activity_record(ar)

        activity_records = mock_config_with_activitystore[0].get_activity_records()
        assert len(activity_records) == 3
        assert activity_records[0].commit == record3.commit
        assert activity_records[0].linked_commit == record3.linked_commit
        assert activity_records[0].message == record3.message
        assert activity_records[1].commit == record2.commit
        assert activity_records[1].linked_commit == record2.linked_commit
        assert activity_records[1].message == record2.message
        assert activity_records[2].commit == record1.commit
        assert activity_records[2].linked_commit == record1.linked_commit
        assert activity_records[2].message == record1.message
        assert activity_records[2].username == 'default'
        assert activity_records[2].email == '*****@*****.**'

        activity_records = mock_config_with_activitystore[0].get_activity_records(first=20)
        assert len(activity_records) == 3
        assert activity_records[0].commit == record3.commit
        assert activity_records[0].linked_commit == record3.linked_commit
        assert activity_records[0].message == record3.message
        assert activity_records[1].commit == record2.commit
        assert activity_records[1].linked_commit == record2.linked_commit
        assert activity_records[1].message == record2.message
        assert activity_records[2].commit == record1.commit
        assert activity_records[2].linked_commit == record1.linked_commit
        assert activity_records[2].message == record1.message
        assert activity_records[2].username == 'default'
        assert activity_records[2].email == '*****@*****.**'

        # Verify the timestamp is getting set properly
        assert type(activity_records[0].timestamp) == datetime
        assert activity_records[0].timestamp < datetime.now(timezone.utc)
        assert activity_records[0].timestamp > datetime.now(timezone.utc) - timedelta(seconds=10)

        activity_records = mock_config_with_activitystore[0].get_activity_records(first=1)
        assert len(activity_records) == 1
        assert activity_records[0].commit == record3.commit
        assert activity_records[0].linked_commit == record3.linked_commit
        assert activity_records[0].message == record3.message

        activity_records = mock_config_with_activitystore[0].get_activity_records(after=record2.commit)
        assert len(activity_records) == 1
        assert activity_records[0].commit == record1.commit
        assert activity_records[0].linked_commit == record1.linked_commit
        assert activity_records[0].message == record1.message

        activity_records = mock_config_with_activitystore[0].get_activity_records(after=record3.commit, first=1)
        assert len(activity_records) == 1
        assert activity_records[0].commit == record2.commit
        assert activity_records[0].linked_commit == record2.linked_commit
        assert activity_records[0].message == record2.message

        activity_records = mock_config_with_activitystore[0].get_activity_records(after=record3.commit, first=20)
        assert len(activity_records) == 2
        assert activity_records[0].commit == record2.commit
        assert activity_records[0].linked_commit == record2.linked_commit
        assert activity_records[0].message == record2.message