[Feedback] IDEBIS-57 Add new module for A/B tests

IJ-CR-126489

GitOrigin-RevId: b15d1372aaf8e8309d2d46ffdb4e2584f627f638
This commit is contained in:
Dmitry Pogrebnoy
2024-02-20 10:36:36 +01:00
committed by intellij-monorepo-bot
parent 6960f1411f
commit 2f5c466e02
8 changed files with 155 additions and 0 deletions

View File

@@ -26,5 +26,6 @@
</orderEntry>
<orderEntry type="module" module-name="intellij.platform.ide.impl" />
<orderEntry type="module" module-name="intellij.idea.customization.base" />
<orderEntry type="module" module-name="intellij.platform.experiment" scope="RUNTIME" />
</component>
</module>

View File

@@ -16,6 +16,7 @@
<module name="intellij.platform.ml.embeddings"/>
<module name="intellij.ide.startup.importSettings"/>
<module name="intellij.kotlin.onboarding-promoter"/>
<module name="intellij.platform.experiment"/>
</content>
<extensions defaultExtensionNs="com.intellij">

View File

@@ -0,0 +1,32 @@
<?xml version="1.0" encoding="UTF-8"?>
<module type="JAVA_MODULE" version="4">
<component name="FacetManager">
<facet type="kotlin-language" name="Kotlin">
<configuration version="5" platform="JVM 17" allPlatforms="JVM [17]" useProjectSettings="false">
<compilerSettings>
<option name="additionalArguments" value="-Xjvm-default=all" />
</compilerSettings>
<compilerArguments>
<stringArguments>
<stringArg name="jvmTarget" arg="17" />
<stringArg name="apiVersion" arg="1.9" />
<stringArg name="languageVersion" arg="1.9" />
</stringArguments>
</compilerArguments>
</configuration>
</facet>
</component>
<component name="NewModuleRootManager" inherit-compiler-output="true">
<exclude-output />
<content url="file://$MODULE_DIR$">
<sourceFolder url="file://$MODULE_DIR$/resources" type="java-resource" />
<sourceFolder url="file://$MODULE_DIR$/src" isTestSource="false" />
</content>
<orderEntry type="inheritedJdk" />
<orderEntry type="sourceFolder" forTests="false" />
<orderEntry type="library" name="kotlin-stdlib" level="project" />
<orderEntry type="module" module-name="intellij.platform.core" />
<orderEntry type="module" module-name="intellij.platform.statistics" />
<orderEntry type="module" module-name="intellij.platform.editor" />
</component>
</module>

View File

@@ -0,0 +1,5 @@
<idea-plugin package="com.intellij.platform.experiment">
<actions>
<action class="com.intellij.platform.experiment.demo.DemoABExperimentAction" internal="true"/>
</actions>
</idea-plugin>

View File

@@ -0,0 +1,69 @@
// Copyright 2000-2024 JetBrains s.r.o. and contributors. Use of this source code is governed by the Apache 2.0 license.
package com.intellij.platform.experiment.ab
import com.intellij.internal.statistic.eventLog.EventLogConfiguration
import com.intellij.openapi.util.registry.Registry
import com.intellij.util.PlatformUtils
// Copyright 2000-2024 JetBrains s.r.o. and contributors. Use of this source code is governed by the Apache 2.0 license.
abstract class ABExperiment<T : ABExperimentConfigBase> {
abstract val id: String
protected abstract val experimentConfig: T
protected abstract val testRegistryKey: String
fun isExperimentEnabled(): Boolean {
return getUserGroupKind() == GroupKind.Experimental
}
fun getUserGroupNumber(): Int {
val testRegistryExperimentGroup = Registry.intValue(testRegistryKey, -1, -1, experimentConfig.totalNumberOfBuckets - 1)
if (testRegistryExperimentGroup >= 0) return testRegistryExperimentGroup
val bucket = getBucket()
val experimentGroup = bucket % getTotalNumberOfGroups()
return experimentGroup
}
fun getUserGroupKind(): GroupKind {
val groupNumber = getUserGroupNumber()
return if (isPopularIDE()) {
when (groupNumber) {
in experimentConfig.experimentalGroupNumbersForPopularIde -> GroupKind.Experimental
in experimentConfig.controlGroupNumbersForPopularIde -> GroupKind.Control
else -> GroupKind.Experimental
}
}
else {
when (groupNumber) {
in experimentConfig.experimentalGroupNumbersForRegularIde -> GroupKind.Experimental
in experimentConfig.controlGroupNumbersForRegularIde -> GroupKind.Control
else -> GroupKind.Experimental
}
}
}
private fun getTotalNumberOfGroups(): Int {
return if (isPopularIDE()) {
experimentConfig.experimentalGroupNumbersForPopularIde.size + experimentConfig.controlGroupNumbersForPopularIde.size
}
else {
experimentConfig.experimentalGroupNumbersForRegularIde.size + experimentConfig.controlGroupNumbersForRegularIde.size
}
}
private fun getBucket(): Int {
val eventLogConfiguration = EventLogConfiguration.getInstance()
return eventLogConfiguration.bucket % experimentConfig.totalNumberOfBuckets
}
private fun isPopularIDE() = PlatformUtils.isIdeaUltimate() || PlatformUtils.isPyCharmPro()
enum class GroupKind {
Experimental,
Control
}
}

View File

@@ -0,0 +1,10 @@
// Copyright 2000-2024 JetBrains s.r.o. and contributors. Use of this source code is governed by the Apache 2.0 license.
package com.intellij.platform.experiment.ab
abstract class ABExperimentConfigBase {
open val experimentalGroupNumbersForPopularIde = (0..7).toList()
open val controlGroupNumbersForPopularIde = listOf(8, 9)
open val experimentalGroupNumbersForRegularIde = listOf(0, 1)
open val controlGroupNumbersForRegularIde = listOf(2)
open val totalNumberOfBuckets = 256
}

View File

@@ -0,0 +1,24 @@
// Copyright 2000-2024 JetBrains s.r.o. and contributors. Use of this source code is governed by the Apache 2.0 license.
package com.intellij.platform.experiment.demo
import com.intellij.openapi.application.ApplicationManager
import com.intellij.openapi.components.Service
import com.intellij.openapi.components.service
import com.intellij.platform.experiment.ab.ABExperiment
import com.intellij.platform.experiment.ab.ABExperimentConfigBase
fun getInstance(): DemoABExperiment {
return ApplicationManager.getApplication().service<DemoABExperiment>()
}
@Service
class DemoABExperiment : ABExperiment<ABExperimentConfigBase>() {
override val id: String = "demo.ab_experiment"
override val experimentConfig: ABExperimentConfigBase = object : ABExperimentConfigBase() {}
override val testRegistryKey: String = "demo.ab_experiment"
}

View File

@@ -0,0 +1,13 @@
// Copyright 2000-2023 JetBrains s.r.o. and contributors. Use of this source code is governed by the Apache 2.0 license.
package com.intellij.platform.experiment.demo
import com.intellij.openapi.actionSystem.AnAction
import com.intellij.openapi.actionSystem.AnActionEvent
class DemoABExperimentAction : AnAction("Aaaaaaa test") {
override fun actionPerformed(e: AnActionEvent) {
println(getInstance().isExperimentEnabled())
println(getInstance().getUserGroupKind())
println(getInstance().getUserGroupNumber())
}
}